diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..fc6c26d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: Tests + +on: + push: + pull_request: + +jobs: + test: + name: Run on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Clone the code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Running Tests + run: | + go mod tidy + go test ./... -covermode=atomic diff --git a/go.mod b/go.mod index 6761cbc..5f3f8bd 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module github.com/pdok/ogc-specifications -go 1.16 +go 1.24 -require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b +require gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index e387ff0..2a2d1a3 100644 --- a/go.sum +++ b/go.sum @@ -2,3 +2,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/common/exception.go b/pkg/common/exception.go new file mode 100644 index 0000000..b2e351d --- /dev/null +++ b/pkg/common/exception.go @@ -0,0 +1,7 @@ +package common + +type ExceptionDetails struct { + ExceptionText string `xml:",chardata" yaml:"exception"` + ExceptionCode string `xml:"code,attr" yaml:"exceptionCode"` + LocatorCode string `xml:"locator,attr,omitempty" yaml:"locatorCode"` +} diff --git a/pkg/wcs201/capabilities.go b/pkg/wcs201/capabilities.go index 2930d87..50947f9 100644 --- a/pkg/wcs201/capabilities.go +++ b/pkg/wcs201/capabilities.go @@ -12,87 +12,121 @@ func (c *Capabilities) ParseYAML(doc []byte) error { // Capabilities struct type Capabilities struct { - OperationsMetadata OperationsMetadata `xml:"ows:OperationsMetadata" yaml:"operationsmetadata"` - ServiceMetadata ServiceMetadata `xml:"wcs:ServiceMetadata" yaml:"servicemetadata"` + OperationsMetadata OperationsMetadata `xml:"ows:OperationsMetadata" yaml:"operationsMetadata"` + ServiceMetadata ServiceMetadata `xml:"wcs:ServiceMetadata" yaml:"serviceMetadata"` Contents Contents `xml:"wcs:Contents" yaml:"contents"` } // OperationsMetadata struct for the WCS 2.0.1 type OperationsMetadata struct { Operation []Operation `xml:"ows:Operation" yaml:"operation"` - ExtendedCapabilities *ExtendedCapabilities `xml:"ows:ExtendedCapabilities" yaml:"extendedcapabilities"` + ExtendedCapabilities *ExtendedCapabilities `xml:"ows:ExtendedCapabilities" yaml:"extendedCapabilities"` } // Operation in struct for repeatability type Operation struct { Name string `xml:"name,attr" yaml:"name"` - DCP struct { - HTTP struct { - Get struct { - Type string `xml:"xlink:type,attr" yaml:"type"` - Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"ows:Get" yaml:"get"` - Post *Post `xml:"ows:Post" yaml:"post"` - } `xml:"ows:HTTP" yaml:"http"` - } `xml:"ows:DCP" yaml:"dcp"` + DCP DCP `xml:"ows:DCP" yaml:"dcp"` +} + +// DCP struct for the WCS 2.0.1 +type DCP struct { + HTTP HTTP `xml:"ows:HTTP" yaml:"http"` +} + +// HTTP struct for the WCS 2.0.1 +type HTTP struct { + Get Get `xml:"ows:Get" yaml:"get"` + Post *Post `xml:"ows:Post" yaml:"post"` +} + +// Get struct for the WCS 2.0.1 +type Get struct { + Type string `xml:"xlink:type,attr" yaml:"type"` + Href string `xml:"xlink:href,attr" yaml:"href"` } // Post in separated struct so to use it as a Pointer type Post struct { - Type string `xml:"xlink:type,attr" yaml:"type"` - Href string `xml:"xlink:href,attr" yaml:"href"` - Constraint struct { - Name string `xml:"name,attr" yaml:"name"` - AllowedValues struct { - Value []string `xml:"ows:Value" yaml:"value"` - } `xml:"ows:AllowedValues" yaml:"allowedvalues"` - } `xml:"ows:Constraint" yaml:"constraint"` + Type string `xml:"xlink:type,attr" yaml:"type"` + Href string `xml:"xlink:href,attr" yaml:"href"` + Constraint Constraint `xml:"ows:Constraint" yaml:"constraint"` +} + +// Constraint struct for the WCS 2.0.1 +type Constraint struct { + Name string `xml:"name,attr" yaml:"name"` + AllowedValues AllowedValues `xml:"ows:AllowedValues" yaml:"allowedValues"` +} + +// AllowedValues struct for the WCS 2.0.1 +type AllowedValues struct { + Value []string `xml:"ows:Value" yaml:"value"` } // ExtendedCapabilities struct for the WCS 2.0.1 type ExtendedCapabilities struct { - ExtendedCapabilities struct { - MetadataURL struct { - URL string `xml:"inspire_common:URL"` - MediaType string `xml:"inspire_common:MediaType"` - } `xml:"inspire_common:MetadataUrl"` - SupportedLanguages struct { - DefaultLanguage struct { - Language string `xml:"inspire_common:Language"` - } `xml:"inspire_common:DefaultLanguage"` - SupportedLanguage *[]struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:SupportedLanguage" yaml:"supportedlanguage"` - } `xml:"inspire_common:SupportedLanguages"` - ResponseLanguage struct { - Language string `xml:"inspire_common:Language"` - } `xml:"inspire_common:ResponseLanguage"` - SpatialDataSetIdentifier struct { - Code string `xml:"Code"` - } `xml:"inspire_dls:SpatialDataSetIdentifier"` - } `xml:"inspire_dls:ExtendedCapabilities"` + ExtendedCapabilities NestedExtendedCapabilities `xml:"inspire_dls:ExtendedCapabilities" yaml:"extendedCapabilities"` +} + +// NestedExtendedCapabilities struct for the WCS 2.0.1 +type NestedExtendedCapabilities struct { + MetadataURL MetadataURL `xml:"inspire_common:MetadataUrl"` + ResponseLanguage Language `xml:"inspire_common:ResponseLanguage" yaml:"responseLanguage"` + SpatialDataSetIdentifier SpatialDataSetIdentifier `xml:"inspire_dls:SpatialDataSetIdentifier" yaml:"spatialDataSetIdentifier"` +} + +// MetadataURL struct { struct for the WCS 2.0.1 +type MetadataURL struct { + URL string `xml:"inspire_common:URL" yaml:"url"` + MediaType string `xml:"inspire_common:MediaType" yaml:"mediaType"` +} + +// SupportedLanguages struct for the struct for the WCS 2.0.1 +type SupportedLanguages struct { + DefaultLanguage Language `xml:"inspire_common:DefaultLanguage" yaml:"defaultLanguage"` + SupportedLanguage *[]Language `xml:"inspire_common:SupportedLanguage" yaml:"supportedLanguage"` +} + +// Language struct for the WCS 2.0.1 +type Language struct { + Language string `xml:"inspire_common:Language" yaml:"language"` +} + +// SpatialDataSetIdentifier struct for the WCS 2.0.1 +type SpatialDataSetIdentifier struct { + Code string `xml:"Code" yaml:"code"` } // ServiceMetadata struct for the WCS 2.0.1 type ServiceMetadata struct { - FormatSupported []string `xml:"wcs:formatSupported"` - Extension struct { - InterpolationMetadata struct { - InterpolationSupported []string `xml:"int:InterpolationSupported"` - } `xml:"int:InterpolationMetadata"` - CrsMetadata struct { - CrsSupported []string `xml:"crs:crsSupported"` - } `xml:"crs:CrsMetadata"` - } `xml:"wcs:Extension"` + FormatSupported []string `xml:"wcs:formatSupported" yaml:"formatSupported"` + Extension Extension `xml:"wcs:Extension" yaml:"extension"` +} + +// Extension struct for the WCS 2.0.1 +type Extension struct { + InterpolationMetadata InterpolationMetadata `xml:"int:InterpolationMetadata" yaml:"interpolationMetadata"` + CrsMetadata CrsMetadata `xml:"crs:CrsMetadata" yaml:"crsMetadata"` +} + +// InterpolationMetadata struct for the WCS 2.0.1 +type InterpolationMetadata struct { + InterpolationSupported []string `xml:"int:InterpolationSupported" yaml:"interpolationSupported"` +} + +// CrsMetadata struct for the WCS 2.0.1 +type CrsMetadata struct { + CrsSupported []string `xml:"crs:crsSupported" yaml:"crsSupported"` } // Contents in struct for repeatability type Contents struct { - CoverageSummary []CoverageSummary `xml:"wcs:CoverageSummary"` + CoverageSummary []CoverageSummary `xml:"wcs:CoverageSummary" yaml:"coverageSummary"` } // CoverageSummary in struct for repeatability type CoverageSummary struct { - CoverageID string `xml:"wcs:CoverageId"` - CoverageSubtype string `xml:"wcs:CoverageSubtype"` + CoverageID string `xml:"wcs:CoverageId" yaml:"coverageId"` + CoverageSubtype string `xml:"wcs:CoverageSubtype" yaml:"coverageSubtype"` } diff --git a/pkg/wcs201/getcapabilities_request.go b/pkg/wcs201/getcapabilities_request.go index e72dcd9..449b37b 100644 --- a/pkg/wcs201/getcapabilities_request.go +++ b/pkg/wcs201/getcapabilities_request.go @@ -86,8 +86,8 @@ func (gc GetCapabilitiesRequest) ToXML() []byte { // GetCapabilitiesRequest struct with the needed parameters/attributes needed for making a GetCapabilities request type GetCapabilitiesRequest struct { - XMLName xml.Name `xml:"GetCapabilities" yaml:"getcapabilities"` + XMLName xml.Name `xml:"GetCapabilities" yaml:"getCapabilities"` Service string `xml:"service,attr" yaml:"service"` Version string `xml:"version,attr" yaml:"version"` - Attr utils.XMLAttribute `xml:",attr"` + Attr utils.XMLAttribute `xml:",attr" yaml:"attr"` } diff --git a/pkg/wcs201/getcapabilities_response.go b/pkg/wcs201/getcapabilities_response.go index 1047739..44d7096 100644 --- a/pkg/wcs201/getcapabilities_response.go +++ b/pkg/wcs201/getcapabilities_response.go @@ -31,11 +31,13 @@ func (gc GetCapabilitiesResponse) ToXML() []byte { // GetCapabilitiesResponse base struct type GetCapabilitiesResponse struct { - XMLName xml.Name `xml:"wcs:Capabilities"` - Namespaces `yaml:"namespaces"` - ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceidentification"` - ServiceProvider ServiceProvider `xml:"ows:ServiceProvider" yaml:"serviceprovider"` - Capabilities + XMLName xml.Name `xml:"wcs:Capabilities" yaml:"wcsCapabilities"` + Namespaces + ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceIdentification"` + ServiceProvider ServiceProvider `xml:"ows:ServiceProvider" yaml:"serviceProvider"` + OperationsMetadata OperationsMetadata `xml:"ows:OperationsMetadata" yaml:"operationsMetadata"` + ServiceMetadata ServiceMetadata `xml:"wcs:ServiceMetadata" yaml:"serviceMetadata"` + Contents Contents `xml:"wcs:Contents" yaml:"contents"` } // Namespaces struct containing the namespaces needed for the XML document @@ -48,59 +50,80 @@ type Namespaces struct { XmlnsGML string `xml:"xmlns:gml,attr" yaml:"gml"` //http://www.opengis.net/gml/3.2 XmlnsGMLcov string `xml:"xmlns:gmlcov,attr" yaml:"gmlcov"` //http://www.opengis.net/gmlcov/1.0 XmlnsSWE string `xml:"xmlns:swe,attr" yaml:"swe"` //http://www.opengis.net/swe/2.0 - XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspirecommon"` //http://inspire.ec.europa.eu/schemas/common/1.0 - XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspiredls"` //http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 + XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspireCommon"` //http://inspire.ec.europa.eu/schemas/common/1.0 + XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspireDls"` //http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 XmlnsCrs string `xml:"xmlns:crs,attr" yaml:"crs"` //http://www.opengis.net/wcs/crs/1.0 XmlnsInt string `xml:"xmlns:int,attr" yaml:"int"` //http://www.opengis.net/wcs/interpolation/1.0 Version string `xml:"version,attr" yaml:"version"` - SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemalocation"` + SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemaLocation"` } // ServiceIdentification struct should only be fill by the "template" configuration wcs201.yaml type ServiceIdentification struct { - Title string `xml:"ows:Title" yaml:"title"` - Abstract string `xml:"ows:Abstract" yaml:"abstract"` - Keywords *wsc200.Keywords `xml:"ows:Keywords" yaml:"keywords"` - ServiceType struct { - Text string `xml:",chardata" yaml:"text"` - CodeSpace string `xml:"codeSpace,attr" yaml:"codespace"` - } `xml:"ows:ServiceType" yaml:"servicetype"` - ServiceTypeVersion []string `xml:"ows:ServiceTypeVersion" yaml:"servicetypeversion"` - Profile []string `xml:"ows:Profile" yaml:"profile"` - Fees string `xml:"ows:Fees" yaml:"fees"` - AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessconstraints"` + Title string `xml:"ows:Title" yaml:"title"` + Abstract string `xml:"ows:Abstract" yaml:"abstract"` + Keywords *wsc200.Keywords `xml:"ows:Keywords" yaml:"keywords"` + ServiceType ServiceType `xml:"ows:ServiceType" yaml:"serviceType"` + ServiceTypeVersion []string `xml:"ows:ServiceTypeVersion" yaml:"serviceTypeVersion"` + Profile []string `xml:"ows:Profile" yaml:"profile"` + Fees string `xml:"ows:Fees" yaml:"fees"` + AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessConstraints"` +} + +// ServiceType struct containing the service type +type ServiceType struct { + Text string `xml:",chardata" yaml:"text"` + CodeSpace string `xml:"codeSpace,attr" yaml:"codeSpace"` } // ServiceProvider struct containing the provider/organization information should only be fill by the "template" configuration wcs201.yaml type ServiceProvider struct { - ProviderName string `xml:"ows:ProviderName" yaml:"providername"` - ProviderSite struct { - Type string `xml:"xlink:type,attr" yaml:"type"` - Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"ows:ProviderSite" yaml:"providersite"` - ServiceContact struct { - IndividualName string `xml:"ows:IndividualName" yaml:"individualname"` - PositionName string `xml:"ows:PositionName" yaml:"positionname"` - ContactInfo struct { - Phone struct { - Voice string `xml:"ows:Voice" yaml:"voice"` - Facsimile string `xml:"ows:Facsimile" yaml:"facsimile"` - } `xml:"ows:Phone" yaml:"phone"` - Address struct { - DeliveryPoint string `xml:"ows:DeliveryPoint" yaml:"deliverypoint"` - City string `xml:"ows:City" yaml:"city"` - AdministrativeArea string `xml:"ows:AdministrativeArea" yaml:"administrativearea"` - PostalCode string `xml:"ows:PostalCode" yaml:"postalcode"` - Country string `xml:"ows:Country" yaml:"country"` - ElectronicMailAddress string `xml:"ows:ElectronicMailAddress" yaml:"electronicmailaddress"` - } `xml:"ows:Address" yaml:"address"` - OnlineResource *struct { - Type string `xml:"xlink:type,attr,omitempty" yaml:"type"` - Href string `xml:"xlink:href,attr,omitempty" yaml:"href"` - } `xml:"ows:OnlineResource,omitempty" yaml:"onlineresource"` - HoursOfService string `xml:"ows:HoursOfService,omitempty" yaml:"hoursofservice"` - ContactInstructions string `xml:"ows:ContactInstructions,omitempty" yaml:"contactinstructions"` - } `xml:"ows:ContactInfo" yaml:"contactinfo"` - Role string `xml:"ows:Role,omitempty" yaml:"role"` - } `xml:"ows:ServiceContact" yaml:"servicecontact"` + ProviderName string `xml:"ows:ProviderName" yaml:"providerName"` + ProviderSite `xml:"ows:ProviderSite" yaml:"providerSite"` + ServiceContact ServiceContact `xml:"ows:ServiceContact" yaml:"serviceContact"` +} + +// ProviderSite struct containing the website of the provider/organization +type ProviderSite struct { + Type string `xml:"xlink:type,attr" yaml:"type"` + Href string `xml:"xlink:href,attr" yaml:"href"` +} + +// ServiceContact struct containing information for the person to contact +type ServiceContact struct { + IndividualName string `xml:"ows:IndividualName" yaml:"individualName"` + PositionName string `xml:"ows:PositionName" yaml:"positionName"` + ContactInfo ContactInfo `xml:"ows:ContactInfo" yaml:"contactInfo"` + Role string `xml:"ows:Role,omitempty" yaml:"role"` +} + +// ContactInfo struct containing the contact information for the service +type ContactInfo struct { + Phone Phone `xml:"ows:Phone" yaml:"phone"` + Address Address `xml:"ows:Address" yaml:"address"` + OnlineResource *OnlineResource `xml:"ows:OnlineResource,omitempty" yaml:"onlineResource"` + HoursOfService string `xml:"ows:HoursOfService,omitempty" yaml:"hoursOfService"` + ContactInstructions string `xml:"ows:ContactInstructions,omitempty" yaml:"contactInstructions"` +} + +// Phone struct containing the contact telephone or fax number +type Phone struct { + Voice string `xml:"ows:Voice" yaml:"voice"` + Facsimile string `xml:"ows:Facsimile" yaml:"facsimile"` +} + +// Address struct containing the address for the contact supplying the service +type Address struct { + DeliveryPoint string `xml:"ows:DeliveryPoint" yaml:"deliveryPoint"` + City string `xml:"ows:City" yaml:"city"` + AdministrativeArea string `xml:"ows:AdministrativeArea" yaml:"administrativeArea"` + PostalCode string `xml:"ows:PostalCode" yaml:"postalCode"` + Country string `xml:"ows:Country" yaml:"country"` + ElectronicMailAddress string `xml:"ows:ElectronicMailAddress" yaml:"electronicMailAddress"` +} + +// OnlineResource struct containing the top-level web address of a service or service provider +type OnlineResource *struct { + Type string `xml:"xlink:type,attr,omitempty" yaml:"type"` + Href string `xml:"xlink:href,attr,omitempty" yaml:"href"` } diff --git a/pkg/wfs200/capabilities.go b/pkg/wfs200/capabilities.go index ea36d12..d41cb3d 100644 --- a/pkg/wfs200/capabilities.go +++ b/pkg/wfs200/capabilities.go @@ -2,7 +2,6 @@ package wfs200 import ( "encoding/xml" - "github.com/pdok/ogc-specifications/pkg/wsc110" ) @@ -18,9 +17,9 @@ func (c *Capabilities) ParseYAML(doc []byte) error { // Capabilities struct type Capabilities struct { - OperationsMetadata OperationsMetadata `xml:"ows:OperationsMetadata" yaml:"operationsmetadata"` - FeatureTypeList FeatureTypeList `xml:"FeatureTypeList" yaml:"featuretypelist"` - FilterCapabilities FilterCapabilities `xml:"fes:Filter_Capabilities" yaml:"filtercapabilities"` + OperationsMetadata *OperationsMetadata `xml:"ows:OperationsMetadata" yaml:"operationsMetadata,omitempty"` + FeatureTypeList FeatureTypeList `xml:"FeatureTypeList" yaml:"featureTypeList"` + FilterCapabilities *FilterCapabilities `xml:"fes:Filter_Capabilities" yaml:"filterCapabilities,omitempty"` } // Method in separated struct so to use it as a Pointer @@ -31,23 +30,33 @@ type Method struct { // OperationsMetadata struct for the WFS 2.0.0 type OperationsMetadata struct { - XMLName xml.Name `xml:"ows:OperationsMetadata"` - Operation []Operation `xml:"ows:Operation"` - Parameter struct { - Name string `xml:"name,attr" yaml:"name"` - AllowedValues *AllowedValues `xml:"ows:AllowedValues" yaml:"allowedvalues"` - } `xml:"ows:Parameter" yaml:"parameter"` - Constraint []Constraint `xml:"ows:Constraint" yaml:"constraint"` - ExtendedCapabilities *ExtendedCapabilities `xml:"ows:ExtendedCapabilities" yaml:"extendedcapabilities"` + XMLName xml.Name `xml:"ows:OperationsMetadata" yaml:"-"` + Operation []Operation `xml:"ows:Operation" yaml:"operation,omitempty"` + Parameter *Parameter `xml:"ows:Parameter" yaml:"parameter,omitempty"` + Constraint []Constraint `xml:"ows:Constraint" yaml:"constraint,omitempty"` + ExtendedCapabilities *ExtendedCapabilities `xml:"ows:ExtendedCapabilities" yaml:"extendedCapabilities,omitempty"` +} + +// Parameter struct for the WFS 2.0.0 +type Parameter struct { + Name string `xml:"name,attr" yaml:"name"` + AllowedValues *AllowedValues `xml:"ows:AllowedValues" yaml:"allowedValues"` } // Constraint struct for the WFS 2.0.0 type Constraint struct { - Text string `xml:",chardata"` + Text string `xml:",chardata" yaml:"text"` Name string `xml:"name,attr" yaml:"name"` - NoValues *string `xml:"ows:NoValues" yaml:"novalues"` - DefaultValue *string `xml:"ows:DefaultValue" yaml:"defaultvalue"` - AllowedValues *AllowedValues `xml:"ows:AllowedValues" yaml:"allowedvalues"` + NoValues *string `xml:"ows:NoValues" yaml:"noValues"` + DefaultValue *string `xml:"ows:DefaultValue" yaml:"defaultValue"` + AllowedValues *AllowedValues `xml:"ows:AllowedValues" yaml:"allowedValues"` +} + +// ValueConstraint struct for the WFS 2.0.0 +type ValueConstraint struct { + Name string `xml:"name,attr" yaml:"name"` + NoValues string `xml:"ows:NoValues" yaml:"noValues"` + DefaultValue string `xml:"ows:DefaultValue" yaml:"defaultValue"` } // when AllowedValues are defined, NoValues should not be present and vice versa @@ -65,24 +74,21 @@ func (c Constraint) MarshalXML(e *xml.Encoder, start xml.StartElement) error { // Operation struct for the WFS 2.0.0 type Operation struct { - Name string `xml:"name,attr"` - DCP struct { - HTTP struct { - Get *Method `xml:"ows:Get,omitempty" yaml:"get,omitempty"` - Post *Method `xml:"ows:Post,omitempty" yaml:"post,omitempty"` - } `xml:"ows:HTTP" yaml:"http"` - } `xml:"ows:DCP" yaml:"dcp"` - Parameter []struct { - Name string `xml:"name,attr"` - AllowedValues struct { - Value []string `xml:"ows:Value"` - } `xml:"ows:AllowedValues"` - } `xml:"ows:Parameter"` - Constraints []struct { - Name string `xml:"name,attr" yaml:"name"` - NoValues string `xml:"ows:NoValues" yaml:"novalues"` - DefaultValue string `xml:"ows:DefaultValue" yaml:"defaultvalue"` - } `xml:"ows:Constraint" yaml:"constraint"` + Name string `xml:"name,attr" yaml:"name"` + DCP DCP `xml:"ows:DCP" yaml:"dcp"` + Parameter []Parameter `xml:"ows:Parameter" yaml:"parameter"` + Constraints []ValueConstraint `xml:"ows:Constraint" yaml:"constraint"` +} + +// DCP struct for the WFS 2.0.0 +type DCP struct { + HTTP HTTP `xml:"ows:HTTP" yaml:"http"` +} + +// HTTP struct for the WFS 2.0.0 +type HTTP struct { + Get *Method `xml:"ows:Get,omitempty" yaml:"get,omitempty"` + Post *Method `xml:"ows:Post,omitempty" yaml:"post,omitempty"` } // AllowedValues struct so it can be used as a pointer @@ -92,100 +98,158 @@ type AllowedValues struct { // ExtendedCapabilities struct for the WFS 2.0.0 type ExtendedCapabilities struct { - ExtendedCapabilities struct { - Text string `xml:",chardata"` - MetadataURL struct { - URL string `xml:"inspire_common:URL" yaml:"url"` - MediaType string `xml:"inspire_common:MediaType" yaml:"mediatype"` - } `xml:"inspire_common:MetadataUrl" yaml:"metadataurl"` - SupportedLanguages struct { - DefaultLanguage struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:DefaultLanguage" yaml:"defaultlanguage"` - SupportedLanguage *[]struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:SupportedLanguage" yaml:"supportedlanguage"` - } `xml:"inspire_common:SupportedLanguages" yaml:"supportedlanguages"` - ResponseLanguage struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:ResponseLanguage" yaml:"responselanguage"` - SpatialDataSetIdentifier struct { - Code string `xml:"inspire_common:Code" yaml:"code"` - } `xml:"inspire_dls:SpatialDataSetIdentifier" yaml:"spatialdatasetidentifier"` - } `xml:"inspire_dls:ExtendedCapabilities" yaml:"extendedcapabilities"` + ExtendedCapabilities NestedExtendedCapabilities `xml:"inspire_dls:ExtendedCapabilities" yaml:"extendedCapabilities"` +} + +// NestedExtendedCapabilities struct for the WFS 2.0.0 +type NestedExtendedCapabilities struct { + Text *string `xml:",chardata" yaml:"text,omitempty"` + MetadataURL MetadataURL `xml:"inspire_common:MetadataUrl" yaml:"metadataUrl"` + SupportedLanguages SupportedLanguages `xml:"inspire_common:SupportedLanguages" yaml:"supportedLanguages"` + ResponseLanguage Language `xml:"inspire_common:ResponseLanguage" yaml:"responseLanguage"` + SpatialDataSetIdentifier SpatialDataSetIdentifier `xml:"inspire_dls:SpatialDataSetIdentifier" yaml:"spatialDataSetIdentifier"` +} + +// MetadataURL struct for the WFS 2.0.0 +type MetadataURL struct { + URL string `xml:"inspire_common:URL" yaml:"url"` + MediaType string `xml:"inspire_common:MediaType" yaml:"mediaType"` +} + +// SupportedLanguages struct for the WFS 2.0.0 +type SupportedLanguages struct { + DefaultLanguage Language `xml:"inspire_common:DefaultLanguage" yaml:"defaultLanguage"` + SupportedLanguage *[]Language `xml:"inspire_common:SupportedLanguage" yaml:"supportedLanguage,omitempty"` +} + +// Language struct for the WFS 2.0.0 +type Language struct { + Language string `xml:"inspire_common:Language" yaml:"language"` +} + +// SpatialDataSetIdentifier struct for the WFS 2.0.0 +type SpatialDataSetIdentifier struct { + Code string `xml:"inspire_common:Code" yaml:"code"` } // FeatureTypeList struct for the WFS 2.0.0 type FeatureTypeList struct { - XMLName xml.Name `xml:"FeatureTypeList"` - FeatureType []FeatureType `xml:"FeatureType" yaml:"featuretype"` + XMLName xml.Name `xml:"FeatureTypeList" yaml:"-"` + FeatureType []FeatureType `xml:"FeatureType" yaml:"featureType"` } // FeatureType struct for the WFS 2.0.0 type FeatureType struct { - Name string `xml:"Name" yaml:"name"` - Title string `xml:"Title" yaml:"title"` - Abstract string `xml:"Abstract" yaml:"abstract"` - Keywords *[]wsc110.Keywords `xml:"ows:Keywords" yaml:"keywords"` - DefaultCRS *CRS `xml:"DefaultCRS" yaml:"defaultcrs"` - OtherCRS *[]CRS `xml:"OtherCRS" yaml:"othercrs"` - OutputFormats struct { - Format []string `xml:"Format" yaml:"format"` - } `xml:"OutputFormats" yaml:"outputformats"` - WGS84BoundingBox *wsc110.WGS84BoundingBox `xml:"ows:WGS84BoundingBox" yaml:"wgs84boundingbox"` - MetadataURL struct { - Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"MetadataURL" yaml:"metadataurl"` + Name string `xml:"Name" yaml:"name"` + Title string `xml:"Title" yaml:"title"` + Abstract string `xml:"Abstract" yaml:"abstract"` + Keywords *[]wsc110.Keywords `xml:"ows:Keywords" yaml:"keywords"` + DefaultCRS *CRS `xml:"DefaultCRS" yaml:"defaultCrs"` + OtherCRS []*CRS `xml:"OtherCRS" yaml:"otherCrs"` + OutputFormats *OutputFormats `xml:"OutputFormats" yaml:"outputFormats,omitempty"` + WGS84BoundingBox *wsc110.WGS84BoundingBox `xml:"ows:WGS84BoundingBox" yaml:"wgs84BoundingBox,omitempty"` + MetadataURL MetadataHref `xml:"MetadataURL" yaml:"metadataUrl"` +} + +// OutputFormats struct for the WFS 2.0.0 +type OutputFormats struct { + Format []string `xml:"Format" yaml:"format"` +} + +// MetadataHref struct for the WFS 2.0.0 +type MetadataHref struct { + Href string `xml:"xlink:href,attr" yaml:"href"` } // FilterCapabilities struct for the WFS 2.0.0 type FilterCapabilities struct { - Conformance struct { - Constraint []struct { - Name string `xml:"name,attr" yaml:"name"` - NoValues string `xml:"ows:NoValues" yaml:"novalues"` - DefaultValue string `xml:"ows:DefaultValue" yaml:"defaultvalue"` - } `xml:"fes:Constraint" yaml:"constraint"` - } `xml:"fes:Conformance" yaml:"conformance"` - IDCapabilities struct { - ResourceIdentifier struct { - Name string `xml:"name,attr" yaml:"name"` - } `xml:"fes:ResourceIdentifier" yaml:"resourceidentifier"` - } `xml:"fes:Id_Capabilities" yaml:"idcapabilities"` - ScalarCapabilities struct { - LogicalOperators string `xml:"fes:LogicalOperators" yaml:"logicaloperators"` - ComparisonOperators struct { - ComparisonOperator []struct { - Name string `xml:"name,attr"` - } `xml:"fes:ComparisonOperator" yaml:"comparisonoperator"` - } `xml:"fes:ComparisonOperators" yaml:"comparisonoperators"` - } `xml:"fes:Scalar_Capabilities" yaml:"scalarcapabilities"` - SpatialCapabilities struct { - GeometryOperands struct { - GeometryOperand []struct { - Name string `xml:"name,attr"` - } `xml:"fes:GeometryOperand"` - } `xml:"fes:GeometryOperands"` - SpatialOperators struct { - SpatialOperator []struct { - Name string `xml:"name,attr"` - } `xml:"fes:SpatialOperator"` - } `xml:"fes:SpatialOperators"` - } `xml:"fes:Spatial_Capabilities"` + Conformance Conformance `xml:"fes:Conformance" yaml:"conformance"` + IDCapabilities IdCapabilities `xml:"fes:Id_Capabilities" yaml:"idCapabilities"` + ScalarCapabilities ScalarCapabilities `xml:"fes:Scalar_Capabilities" yaml:"scalarCapabilities"` + SpatialCapabilities SpatialCapabilities `xml:"fes:Spatial_Capabilities" yaml:"spatialCapabilities"` // NO TemporalCapabilities!!! - TemporalCapabilities *TemporalCapabilities `xml:"fes:Temporal_Capabilities" yaml:"temporalcapabilities"` + TemporalCapabilities *TemporalCapabilities `xml:"fes:Temporal_Capabilities" yaml:"temporalCapabilities"` +} + +// Conformance struct for the WFS 2.0.0 +type Conformance struct { + Constraint []ValueConstraint `xml:"fes:Constraint" yaml:"constraint"` +} + +// IdCapabilities struct for the WFS 2.0.0 +type IdCapabilities struct { + ResourceIdentifier ResourceIdentifier `xml:"fes:ResourceIdentifier" yaml:"resourceIdentifier"` +} + +// ScalarCapabilities struct for the WFS 2.0.0 +type ScalarCapabilities struct { + LogicalOperators string `xml:"fes:LogicalOperators" yaml:"logicalOperators"` + ComparisonOperators ComparisonOperators `xml:"fes:ComparisonOperators" yaml:"comparisonOperators"` +} + +// ComparisonOperators struct for the WFS 2.0.0 +type ComparisonOperators struct { + ComparisonOperator []ComparisonOperatorName `xml:"fes:ComparisonOperator" yaml:"comparisonOperator"` +} + +// ComparisonOperatorName struct for the WFS 2.0.0 +type ComparisonOperatorName struct { + Name string `xml:"name,attr"` +} + +// SpatialCapabilities struct for the WFS 2.0.0 +type SpatialCapabilities struct { + GeometryOperands GeometryOperands `xml:"fes:GeometryOperands" yaml:"geometryOperands"` + SpatialOperators SpatialOperators `xml:"fes:SpatialOperators" yaml:"spatialOperators"` +} + +// GeometryOperands struct for the WFS 2.0.0 +type GeometryOperands struct { + GeometryOperand []GeometryOperandName `xml:"fes:GeometryOperand" yaml:"geometryOperand"` +} + +// GeometryOperandName struct for the WFS 2.0.0 +type GeometryOperandName struct { + Name string `xml:"name,attr" yaml:"name"` +} + +// SpatialOperators struct for the WFS 2.0.0 +type SpatialOperators struct { + SpatialOperator []SpatialOperatorName `xml:"fes:SpatialOperator" yaml:"spatialOperator"` +} + +// SpatialOperatorName struct for the WFS 2.0.0 +type SpatialOperatorName struct { + Name string `xml:"name,attr" yaml:"name"` +} + +// ResourceIdentifier struct for the WFS 2.0.0 +type ResourceIdentifier struct { + Name string `xml:"name,attr" yaml:"name"` } // TemporalCapabilities define but not used type TemporalCapabilities struct { - TemporalOperands struct { - TemporalOperand []struct { - Name string `xml:"name,attr" yaml:"name"` - } `xml:"fes:TemporalOperand" yaml:"temporaloperand"` - } `xml:"fes:TemporalOperands" yaml:"temporaloperands"` - TemporalOperators struct { - TemporalOperator []struct { - Name string `xml:"name,attr,omitempty" yaml:"name,omitempty"` - } `xml:"fes:TemporalOperator" yaml:"temporaloperator"` - } `xml:"fes:TemporalOperators" yaml:"temporaloperators"` + TemporalOperands TemporalOperands `xml:"fes:TemporalOperands" yaml:"temporalOperands"` + TemporalOperators TemporalOperators `xml:"fes:TemporalOperators" yaml:"temporalOperators"` +} + +// TemporalOperands struct for the WFS 2.0.0 +type TemporalOperands struct { + TemporalOperand []TemporalOperand `xml:"fes:TemporalOperand" yaml:"temporalOperand"` +} + +// TemporalOperand struct for the WFS 2.0.0 +type TemporalOperand struct { + Name string `xml:"name,attr" yaml:"name"` +} + +// TemporalOperators struct for the WFS 2.0.0 +type TemporalOperators struct { + TemporalOperator []TemporalOperator `xml:"fes:TemporalOperator" yaml:"temporalOperator"` +} + +// TemporalOperator struct for the WFS 2.0.0 +type TemporalOperator struct { + Name string `xml:"name,attr,omitempty" yaml:"name,omitempty"` } diff --git a/pkg/wfs200/crs.go b/pkg/wfs200/crs.go index 52a2693..be84ac5 100644 --- a/pkg/wfs200/crs.go +++ b/pkg/wfs200/crs.go @@ -5,7 +5,6 @@ import ( "strconv" ) -// const ( codeSpace = `urn:ogc:def:crs:EPSG:` ) diff --git a/pkg/wfs200/crs_test.go b/pkg/wfs200/crs_test.go index 9175737..52f3fa2 100644 --- a/pkg/wfs200/crs_test.go +++ b/pkg/wfs200/crs_test.go @@ -58,3 +58,25 @@ othercrs: } } } + +func TestMarshalYAMLCrs(t *testing.T) { + var stringYAML = `urn:ogc:def:crs:EPSG::4326 +` + tests := []struct { + CRS *CRS + expectedYAML string + }{ + 0: {CRS: &CRS{Code: 4326, Namespace: codeSpace}, expectedYAML: stringYAML}, + } + for k, test := range tests { + yamlCRS, err := yaml.Marshal(test.CRS) + if err != nil { + t.Errorf("test: %d, yaml.Marshal failed with '%s'\n", k, err) + } else { + stringCRS := string(yamlCRS) + if stringCRS != test.expectedYAML { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedYAML, stringCRS) + } + } + } +} diff --git a/pkg/wfs200/crs_yaml.go b/pkg/wfs200/crs_yaml.go index f040a09..55c2a01 100644 --- a/pkg/wfs200/crs_yaml.go +++ b/pkg/wfs200/crs_yaml.go @@ -14,3 +14,7 @@ func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } + +func (c CRS) MarshalYAML() (interface{}, error) { + return c.String(), nil +} diff --git a/pkg/wfs200/describefeaturetype_benchmark_test.go b/pkg/wfs200/describefeaturetype_benchmark_test.go index 99b6f93..2b32036 100644 --- a/pkg/wfs200/describefeaturetype_benchmark_test.go +++ b/pkg/wfs200/describefeaturetype_benchmark_test.go @@ -15,7 +15,7 @@ func BenchmarkDescribeFeatureTypeToQueryParameters(b *testing.B) { BaseRequest: BaseRequest{Version: Version, Service: Service}, BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{ OutputFormat: sp(`application/json`), - TypeName: sp(`example:example`)}} + TypeNames: sp(`example:example`)}} for i := 0; i < b.N; i++ { df.ToQueryParameters() } @@ -27,7 +27,7 @@ func BenchmarkDescribeFeatureTypeToXML(b *testing.B) { BaseRequest: BaseRequest{Version: Version, Service: Service}, BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{ OutputFormat: sp(`application/json`), - TypeName: sp(`example:example`)}} + TypeNames: sp(`example:example`)}} for i := 0; i < b.N; i++ { df.ToXML() } diff --git a/pkg/wfs200/describefeaturetype_request.go b/pkg/wfs200/describefeaturetype_request.go index 19aa42c..afe806b 100644 --- a/pkg/wfs200/describefeaturetype_request.go +++ b/pkg/wfs200/describefeaturetype_request.go @@ -11,7 +11,6 @@ import ( "strings" ) -// const ( TYPENAME = `TYPENAME` //NOTE: TYPENAME for Parameter Value encoding & typeNames for XML encoding ) @@ -82,7 +81,7 @@ func (d *DescribeFeatureTypeRequest) parsedescribeFeatureTypeRequestParameterVal } d.BaseRequest = br - d.TypeName = dpv.typeName + d.TypeNames = dpv.typeName if dpv.outputFormat != nil { d.OutputFormat = dpv.outputFormat @@ -112,13 +111,13 @@ func (d DescribeFeatureTypeRequest) ToXML() []byte { // DescribeFeatureTypeRequest struct with the needed parameters/attributes needed for making a DescribeFeatureType request type DescribeFeatureTypeRequest struct { - XMLName xml.Name `xml:"DescribeFeatureType" yaml:"describefeaturetype"` + XMLName xml.Name `xml:"DescribeFeatureType" yaml:"describeFeatureType"` BaseRequest BaseDescribeFeatureTypeRequest } // BaseDescribeFeatureTypeRequest struct used by GetFeature type BaseDescribeFeatureTypeRequest struct { - OutputFormat *string `xml:"outputFormat,attr" yaml:"outputformat"` - TypeName *string `xml:"typeNames,attr" yaml:"typenames"` + OutputFormat *string `xml:"outputFormat,attr" yaml:"outputFormat"` + TypeNames *string `xml:"typeNames,attr" yaml:"typeNames"` } diff --git a/pkg/wfs200/describefeaturetype_request_pv.go b/pkg/wfs200/describefeaturetype_request_pv.go index cec2fd9..40784c3 100644 --- a/pkg/wfs200/describefeaturetype_request_pv.go +++ b/pkg/wfs200/describefeaturetype_request_pv.go @@ -8,11 +8,11 @@ import ( ) type describeFeatureTypeRequestParameterValue struct { - service string `yaml:"service"` + service string `yaml:"service" json:"service"` baseParameterValueRequest - typeName *string `yaml:"typename"` // [0..*] - outputFormat *string `yaml:"outputformat"` // default: "text/xml; subtype=gml/3.2" + typeName *string `yaml:"typeName" json:"typeName"` // [0..*] + outputFormat *string `yaml:"outputFormat" json:"outputFormat"` // default: "text/xml; subtype=gml/3.2" } func (dpv *describeFeatureTypeRequestParameterValue) parseQueryParameters(query url.Values) []wsc110.Exception { @@ -49,7 +49,7 @@ func (dpv *describeFeatureTypeRequestParameterValue) parseDescribeFeatureTypeReq dpv.request = describefeaturetype dpv.version = dft.Version dpv.service = dft.Service - dpv.typeName = dft.TypeName + dpv.typeName = dft.TypeNames dpv.outputFormat = dft.OutputFormat return nil } diff --git a/pkg/wfs200/describefeaturetype_response.go b/pkg/wfs200/describefeaturetype_response.go index f05ccae..6b9c98f 100644 --- a/pkg/wfs200/describefeaturetype_response.go +++ b/pkg/wfs200/describefeaturetype_response.go @@ -5,45 +5,45 @@ import "encoding/xml" // Schema struct // TODO build struct based on the capabilities and additional featureinfo type Schema struct { - XMLName xml.Name `xml:"schema"` - Text string `xml:",chardata"` - Xsd string `xml:"xsd,attr"` - Digitaaltopografischbestand string `xml:"digitaaltopografischbestand,attr"` - Gml string `xml:"gml,attr"` - Wfs string `xml:"wfs,attr"` - ElementFormDefault string `xml:"elementFormDefault,attr"` - TargetNamespace string `xml:"targetNamespace,attr"` + XMLName xml.Name `xml:"schema" json:"schema"` + Text string `xml:",chardata" json:"text"` + Xsd string `xml:"xsd,attr" json:"xsd"` + Digitaaltopografischbestand string `xml:"digitaaltopografischbestand,attr" json:"digitaaltopografischbestand"` + Gml string `xml:"gml,attr" json:"gml"` + Wfs string `xml:"wfs,attr" json:"wfs"` + ElementFormDefault string `xml:"elementFormDefault,attr" json:"elementFormDefault"` + TargetNamespace string `xml:"targetNamespace,attr" json:"targetNamespace"` Import struct { - Text string `xml:",chardata"` - Namespace string `xml:"namespace,attr"` - SchemaLocation string `xml:"schemaLocation,attr"` - } `xml:"import"` + Text string `xml:",chardata" json:"text"` + Namespace string `xml:"namespace,attr" json:"namespace"` + SchemaLocation string `xml:"schemaLocation,attr" json:"schemaLocation"` + } `xml:"import" json:"import"` ComplexType []struct { - Text string `xml:",chardata"` - Name string `xml:"name,attr"` + Text string `xml:",chardata" json:"text"` + Name string `xml:"name,attr" json:"name"` ComplexContent struct { - Text string `xml:",chardata"` + Text string `xml:",chardata" json:"text"` Extension struct { - Text string `xml:",chardata"` - Base string `xml:"base,attr"` + Text string `xml:",chardata" json:"text"` + Base string `xml:"base,attr" json:"base"` Sequence struct { - Text string `xml:",chardata"` + Text string `xml:",chardata" json:"text"` Element []struct { - Text string `xml:",chardata"` - MaxOccurs string `xml:"maxOccurs,attr"` - MinOccurs string `xml:"minOccurs,attr"` - Name string `xml:"name,attr"` - Nillable string `xml:"nillable,attr"` - Type string `xml:"type,attr"` - } `xml:"element"` - } `xml:"sequence"` - } `xml:"extension"` - } `xml:"complexContent"` - } `xml:"complexType"` + Text string `xml:",chardata" json:"text"` + MaxOccurs string `xml:"maxOccurs,attr" json:"maxOccurs"` + MinOccurs string `xml:"minOccurs,attr" json:"minOccurs"` + Name string `xml:"name,attr" json:"name"` + Nillable string `xml:"nillable,attr" json:"nillable"` + Type string `xml:"type,attr" json:"type"` + } `xml:"element" json:"element"` + } `xml:"sequence" json:"sequence"` + } `xml:"extension" json:"extension"` + } `xml:"complexContent" json:"complexContent"` + } `xml:"complexType" json:"complexType"` Element []struct { - Text string `xml:",chardata"` - Name string `xml:"name,attr"` - SubstitutionGroup string `xml:"substitutionGroup,attr"` - Type string `xml:"type,attr"` - } `xml:"element"` + Text string `xml:",chardata" json:"text"` + Name string `xml:"name,attr" json:"name"` + SubstitutionGroup string `xml:"substitutionGroup,attr" json:"substitutionGroup"` + Type string `xml:"type,attr" json:"type"` + } `xml:"element" json:"element"` } diff --git a/pkg/wfs200/describefeaturetype_test.go b/pkg/wfs200/describefeaturetype_test.go index 3eff866..29bd9cf 100644 --- a/pkg/wfs200/describefeaturetype_test.go +++ b/pkg/wfs200/describefeaturetype_test.go @@ -52,7 +52,7 @@ func TestDescribeFeatureTypeParseXML(t *testing.T) { Attr: []xml.Attr{{Name: xml.Name{Space: "xmlns", Local: "wfs"}, Value: "http://www.opengis.net/wfs/2.0"}}}}}, 6: {body: []byte(``), result: DescribeFeatureTypeRequest{XMLName: xml.Name{Local: describefeaturetype}, - BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{TypeName: sp("acme:anvils")}, + BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{TypeNames: sp("acme:anvils")}, BaseRequest: BaseRequest{Service: "wfs", Version: "2.0.0"}}}, } @@ -75,9 +75,9 @@ func TestDescribeFeatureTypeParseXML(t *testing.T) { if dft.BaseRequest.Version != test.result.BaseRequest.Version { t.Errorf("test: %d, expected: %+v ,\n got: %+v", k, test.result, dft) } - if dft.BaseDescribeFeatureTypeRequest.TypeName != nil { - if *dft.BaseDescribeFeatureTypeRequest.TypeName != *test.result.BaseDescribeFeatureTypeRequest.TypeName { - t.Errorf("test: %d, expected: %+v ,\n got: %+v", k, *test.result.BaseDescribeFeatureTypeRequest.TypeName, *dft.BaseDescribeFeatureTypeRequest.TypeName) + if dft.BaseDescribeFeatureTypeRequest.TypeNames != nil { + if *dft.BaseDescribeFeatureTypeRequest.TypeNames != *test.result.BaseDescribeFeatureTypeRequest.TypeNames { + t.Errorf("test: %d, expected: %+v ,\n got: %+v", k, *test.result.BaseDescribeFeatureTypeRequest.TypeNames, *dft.BaseDescribeFeatureTypeRequest.TypeNames) } } if len(test.result.BaseRequest.Attr) == len(dft.BaseRequest.Attr) { @@ -123,7 +123,7 @@ func TestDescribeFeatureTypeParseQueryParameters(t *testing.T) { result: DescribeFeatureTypeRequest{XMLName: xml.Name{Local: describefeaturetype}, BaseRequest: BaseRequest{Service: "WFS", Version: "1.1.0"}}}, 5: {query: map[string][]string{VERSION: {Version}, SERVICE: {Service}, REQUEST: {describefeaturetype}, TYPENAME: {"acme:anvils"}}, result: DescribeFeatureTypeRequest{XMLName: xml.Name{Local: describefeaturetype}, - BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{TypeName: sp("acme:anvils")}, + BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{TypeNames: sp("acme:anvils")}, BaseRequest: BaseRequest{Service: Service, Version: Version}}}, 6: {query: map[string][]string{}, exception: []wsc110.Exception{wsc110.MissingParameterValue(VERSION)}, @@ -147,9 +147,9 @@ func TestDescribeFeatureTypeParseQueryParameters(t *testing.T) { if test.result.BaseRequest.Version != dft.BaseRequest.Version { t.Errorf("test: %d, expected: %s ,\n got: %s", k, test.result.BaseRequest.Version, dft.BaseRequest.Version) } - if dft.BaseDescribeFeatureTypeRequest.TypeName != nil { - if *dft.BaseDescribeFeatureTypeRequest.TypeName != *test.result.BaseDescribeFeatureTypeRequest.TypeName { - t.Errorf("test: %d, expected: %+v ,\n got: %+v", k, *test.result.BaseDescribeFeatureTypeRequest.TypeName, *dft.BaseDescribeFeatureTypeRequest.TypeName) + if dft.BaseDescribeFeatureTypeRequest.TypeNames != nil { + if *dft.BaseDescribeFeatureTypeRequest.TypeNames != *test.result.BaseDescribeFeatureTypeRequest.TypeNames { + t.Errorf("test: %d, expected: %+v ,\n got: %+v", k, *test.result.BaseDescribeFeatureTypeRequest.TypeNames, *dft.BaseDescribeFeatureTypeRequest.TypeNames) } } } @@ -165,7 +165,7 @@ func TestDescribeFeatureTypeToQueryParameters(t *testing.T) { BaseRequest: BaseRequest{Version: Version, Service: Service}, BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{ OutputFormat: sp(`application/json`), - TypeName: sp(`example:example`)}}, + TypeNames: sp(`example:example`)}}, query: map[string][]string{"OUTPUTFORMAT": {"application/json"}, "VERSION": {`2.0.0`}, "REQUEST": {"DescribeFeatureType"}, "SERVICE": {"WFS"}, "TYPENAME": {"example:example"}}, }, } @@ -197,7 +197,7 @@ func TestDescribeFeatureTypeToXML(t *testing.T) { BaseRequest: BaseRequest{Version: Version, Service: Service}, BaseDescribeFeatureTypeRequest: BaseDescribeFeatureTypeRequest{ OutputFormat: sp(`application/json`), - TypeName: sp(`example:example`)}}, + TypeNames: sp(`example:example`)}}, body: ` `, }, diff --git a/pkg/wfs200/exception.go b/pkg/wfs200/exception.go index 56a14fa..ecd1337 100644 --- a/pkg/wfs200/exception.go +++ b/pkg/wfs200/exception.go @@ -2,15 +2,14 @@ package wfs200 import ( "encoding/xml" - "github.com/pdok/ogc-specifications/pkg/wsc110" ) type exception struct { - XMLName xml.Name `xml:"ows:Exception"` + XMLName xml.Name `xml:"ows:Exception" yaml:"owsException"` ExceptionText string `xml:",chardata" yaml:"exception"` - ExceptionCode string `xml:"exceptionCode,attr" yaml:"exceptioncode"` - LocatorCode string `xml:"locator,attr,omitempty" yaml:"locationcode"` + ExceptionCode string `xml:"exceptionCode,attr" yaml:"exceptionCode"` + LocatorCode string `xml:"locator,attr,omitempty" yaml:"locatorCode"` } // ToExceptions promotes a single exception to an array of one diff --git a/pkg/wfs200/getcapabilities_request.go b/pkg/wfs200/getcapabilities_request.go index 0fbfde8..e89fbb2 100644 --- a/pkg/wfs200/getcapabilities_request.go +++ b/pkg/wfs200/getcapabilities_request.go @@ -95,8 +95,8 @@ func (g GetCapabilitiesRequest) ToXML() []byte { // GetCapabilitiesRequest struct with the needed parameters/attributes needed for making a GetCapabilities request type GetCapabilitiesRequest struct { - XMLName xml.Name `xml:"GetCapabilities" yaml:"getcapabilities"` + XMLName xml.Name `xml:"GetCapabilities" yaml:"getCapabilities"` Service string `xml:"service,attr" yaml:"service"` Version string `xml:"version,attr" yaml:"version"` - Attr utils.XMLAttribute `xml:",attr"` + Attr utils.XMLAttribute `xml:",attr" yaml:"attr"` } diff --git a/pkg/wfs200/getcapabilities_response.go b/pkg/wfs200/getcapabilities_response.go index 38b5357..e2a993e 100644 --- a/pkg/wfs200/getcapabilities_response.go +++ b/pkg/wfs200/getcapabilities_response.go @@ -38,11 +38,11 @@ func (gc GetCapabilitiesResponse) ToXML() []byte { // GetCapabilitiesResponse base struct type GetCapabilitiesResponse struct { - XMLName xml.Name `xml:"WFS_Capabilities"` - Namespaces `yaml:"namespaces"` - ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceidentification"` - ServiceProvider ServiceProvider `xml:"ows:ServiceProvider" yaml:"serviceprovider"` - Capabilities + XMLName xml.Name `xml:"WFS_Capabilities" yaml:"-"` + *Namespaces `yaml:"namespaces,omitempty"` + ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceIdentification"` + ServiceProvider ServiceProvider `xml:"ows:ServiceProvider" yaml:"serviceProvider"` + Capabilities `yaml:"capabilities"` } // Namespaces struct containing the namespaces needed for the XML document @@ -53,60 +53,81 @@ type Namespaces struct { XmlnsXlink string `xml:"xmlns:xlink,attr" yaml:"xlink"` //http://www.w3.org/1999/xlink XmlnsXSI string `xml:"xmlns:xsi,attr" yaml:"xsi"` //http://www.w3.org/2001/XMLSchema-instance XmlnsFes string `xml:"xmlns:fes,attr" yaml:"fes"` //http://www.opengis.net/fes/2.0 - XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspirecommon,omitempty"` //http://inspire.ec.europa.eu/schemas/common/1.0 - XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspiredls,omitempty"` //http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 + XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspireCommon,omitempty"` //http://inspire.ec.europa.eu/schemas/common/1.0 + XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspireDls,omitempty"` //http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 XmlnsPrefix string `xml:"xmlns:{{.Prefix}},attr" yaml:"prefix"` //namespace_uri placeholder Version string `xml:"version,attr" yaml:"version"` - SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemalocation"` + SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemaLocation"` } -// ServiceIdentification struct should only be fill by the "template" configuration wfs200.yaml +// ServiceIdentification struct should only be filled by the "template" configuration wfs200.yaml type ServiceIdentification struct { - XMLName xml.Name `xml:"ows:ServiceIdentification"` - Title string `xml:"ows:Title" yaml:"title"` - Abstract string `xml:"ows:Abstract" yaml:"abstract"` - Keywords *wsc110.Keywords `xml:"ows:Keywords" yaml:"keywords"` - ServiceType struct { - Text string `xml:",chardata" yaml:"text"` - CodeSpace string `xml:"codeSpace,attr" yaml:"codespace"` - } `xml:"ows:ServiceType"` - ServiceTypeVersion string `xml:"ows:ServiceTypeVersion" yaml:"servicetypeversion"` - Fees string `xml:"ows:Fees" yaml:"fees"` - AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessconstraints"` + XMLName xml.Name `xml:"ows:ServiceIdentification" yaml:"-"` + Title string `xml:"ows:Title" yaml:"title"` + Abstract string `xml:"ows:Abstract" yaml:"abstract"` + Keywords *wsc110.Keywords `xml:"ows:Keywords" yaml:"keywords"` + ServiceType *ServiceType `xml:"ows:ServiceType" yaml:"serviceType,omitempty"` + ServiceTypeVersion *string `xml:"ows:ServiceTypeVersion" yaml:"serviceTypeVersion,omitempty"` + Fees *string `xml:"ows:Fees" yaml:"fees,omitempty"` + AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessConstraints"` +} + +// ServiceType struct containing the service type +type ServiceType struct { + Text string `xml:",chardata" yaml:"text"` + CodeSpace string `xml:"codeSpace,attr" yaml:"codeSpace"` } // ServiceProvider struct containing the provider/organization information should only be fill by the "template" configuration wfs200.yaml type ServiceProvider struct { - XMLName xml.Name `xml:"ows:ServiceProvider"` - ProviderName string `xml:"ows:ProviderName" yaml:"providername"` - ProviderSite struct { - Type string `xml:"xlink:type,attr" yaml:"type"` - Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"ows:ProviderSite" yaml:"providersite"` - ServiceContact struct { - IndividualName string `xml:"ows:IndividualName" yaml:"individualname"` - PositionName string `xml:"ows:PositionName" yaml:"positionname"` - ContactInfo struct { - Text string `xml:",chardata"` - Phone struct { - Voice string `xml:"ows:Voice" yaml:"voice"` - Facsimile string `xml:"ows:Facsimile" yaml:"facsmile"` - } `xml:"ows:Phone" yaml:"phone"` - Address struct { - DeliveryPoint string `xml:"ows:DeliveryPoint" yaml:"deliverypoint"` - City string `xml:"ows:City" yaml:"city"` - AdministrativeArea string `xml:"ows:AdministrativeArea" yaml:"administrativearea"` - PostalCode string `xml:"ows:PostalCode" yaml:"postalcode"` - Country string `xml:"ows:Country" yaml:"country"` - ElectronicMailAddress string `xml:"ows:ElectronicMailAddress" yaml:"electronicmailaddress"` - } `xml:"ows:Address" yaml:"address"` - OnlineResource struct { - Type string `xml:"xlink:type,attr" yaml:"type"` - Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"ows:OnlineResource" yaml:"onlineresource"` - HoursOfService string `xml:"ows:HoursOfService" yaml:"hoursofservice"` - ContactInstructions string `xml:"ows:ContactInstructions" yaml:"contactinstructions"` - } `xml:"ows:ContactInfo" yaml:"contactinfo"` - Role string `xml:"ows:Role" yaml:"role"` - } `xml:"ows:ServiceContact" yaml:"servicecontact"` + XMLName xml.Name `xml:"ows:ServiceProvider" yaml:"-"` + ProviderName *string `xml:"ows:ProviderName" yaml:"providerName,omitempty"` + ProviderSite *ProviderSite `xml:"ows:ProviderSite" yaml:"providerSite,omitempty"` + ServiceContact *ServiceContact `xml:"ows:ServiceContact" yaml:"serviceContact,omitempty"` +} + +// ProviderSite struct containing the website of the provider/organization +type ProviderSite struct { + Type string `xml:"xlink:type,attr" yaml:"type"` + Href string `xml:"xlink:href,attr" yaml:"href"` +} + +// ServiceContact struct containing information for the person to contact +type ServiceContact struct { + IndividualName *string `xml:"ows:IndividualName" yaml:"individualName,omitempty"` + PositionName *string `xml:"ows:PositionName" yaml:"positionName,omitempty"` + ContactInfo *ContactInfo `xml:"ows:ContactInfo" yaml:"contactInfo,omitempty"` + Role *string `xml:"ows:Role" yaml:"role,omitempty"` +} + +// ContactInfo struct containing the contact information for the service +type ContactInfo struct { + Text *string `xml:",chardata" yaml:"text,omitempty"` + Phone *Phone `xml:"ows:Phone" yaml:"phone,omitempty"` + Address *Address `xml:"ows:Address" yaml:"address,omitempty"` + OnlineResource *OnlineResource `xml:"ows:OnlineResource" yaml:"onlineResource,omitempty"` + HoursOfService *string `xml:"ows:HoursOfService" yaml:"hoursOfService,omitempty"` + ContactInstructions *string `xml:"ows:ContactInstructions" yaml:"contactInstructions,omitempty"` +} + +// Phone struct containing the contact telephone or fax number +type Phone struct { + Voice *string `xml:"ows:Voice" yaml:"voice,omitempty"` + Facsimile *string `xml:"ows:Facsimile" yaml:"facsimile,omitempty"` +} + +// Address struct containing the address for the contact supplying the service +type Address struct { + DeliveryPoint *string `xml:"ows:DeliveryPoint" yaml:"deliveryPoint,omitempty"` + City *string `xml:"ows:City" yaml:"city,omitempty"` + AdministrativeArea *string `xml:"ows:AdministrativeArea" yaml:"administrativeArea,omitempty"` + PostalCode *string `xml:"ows:PostalCode" yaml:"postalCode,omitempty"` + Country *string `xml:"ows:Country" yaml:"country,omitempty"` + ElectronicMailAddress *string `xml:"ows:ElectronicMailAddress" yaml:"electronicMailAddress,omitempty"` +} + +// OnlineResource struct containing the top-level web address of a service or service provider +type OnlineResource struct { + Type *string `xml:"xlink:type,attr" yaml:"type,omitempty"` + Href *string `xml:"xlink:href,attr" yaml:"href,omitempty"` } diff --git a/pkg/wfs200/getfeature_request.go b/pkg/wfs200/getfeature_request.go index 6f1c726..33b9889 100644 --- a/pkg/wfs200/getfeature_request.go +++ b/pkg/wfs200/getfeature_request.go @@ -14,7 +14,6 @@ import ( // Contains the GetFeature struct and specific functions for building a GetFeature request -// const ( // table5 @@ -64,8 +63,8 @@ func (f GetFeatureRequest) Validate(c wsc110.Capabilities) []wsc110.Exception { // WFS tables as map[string]bool, where the key (string) is the TOKEN and the bool if its a mandatory (true) or optional (false) attribute //var table5 = map[string]bool{STARTINDEX: false, COUNT: false, OUTPUTFORMAT: false, RESULTTYPE: false} -//var table6 = map[string]bool{RESOLVE: false, RESOLVEDEPTH: false, RESOLVETIMEOUT: false} -//var table7 = map[string]bool{NAMESPACES: false} //VSPs (<- vendor specific parameters) +// var table6 = map[string]bool{RESOLVE: false, RESOLVEDEPTH: false, RESOLVETIMEOUT: false} +// var table7 = map[string]bool{NAMESPACES: false} //VSPs (<- vendor specific parameters) var table8 = map[string]bool{TYPENAMES: true, ALIASES: false, SRSNAME: false, FILTER: false, FILTERLANGUAGE: false, RESOURCEID: false, BBOX: false, SORTBY: false} //var table10 = map[string]bool{STOREDQUERYID: true} //storedquery_parameter=value @@ -194,10 +193,10 @@ func procesNamespaces(namespace string) []xml.Attr { // StandardPresentationParameters struct used by GetFeature type StandardPresentationParameters struct { - ResultType *string `xml:"resultType,attr,omitempty" yaml:"resulttype"` // enum: "results" or "hits" - OutputFormat *string `xml:"outputFormat,attr,omitempty" yaml:"outputformat"` // default "application/gml+xml; version=3.2" + ResultType *string `xml:"resultType,attr,omitempty" yaml:"resultType"` // enum: "results" or "hits" + OutputFormat *string `xml:"outputFormat,attr,omitempty" yaml:"outputFormat"` // default "application/gml+xml; version=3.2" Count *int `xml:"count,attr,omitempty" yaml:"count"` - Startindex *int `xml:"startindex,attr,omitempty" yaml:"startindex"` // default 0 + StartIndex *int `xml:"startindex,attr,omitempty" yaml:"startIndex"` // default 0 } func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestParameterValue) []wsc110.Exception { @@ -225,7 +224,7 @@ func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestPa if err != nil { exceptions = append(exceptions, wsc110.MissingParameterValue(STARTINDEX, *fpv.startindex)) } - b.Startindex = &startindex + b.StartIndex = &startindex } } @@ -239,17 +238,17 @@ func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestPa // contains the resolve information of a GetFeauter request type StandardResolveParameters struct { Resolve *string `xml:"Resolve,omitempty" yaml:"resolve"` //can be one of: local, remote, all, none - ResolveDepth *int `xml:"ResolveDepth,omitempty" yaml:"resolvedepth"` - ResolveTimeout *int `xml:"ResolveTimeout,omitempty" yaml:"resolvetimeout"` + ResolveDepth *int `xml:"ResolveDepth,omitempty" yaml:"resolveDepth"` + ResolveTimeout *int `xml:"ResolveTimeout,omitempty" yaml:"resolveTimeout"` } // Query struct for parsing the WFS filter xml type Query struct { - TypeNames string `xml:"typeNames,attr" yaml:"typenames"` - SrsName *string `xml:"srsName,attr" yaml:"srsname"` + TypeNames string `xml:"typeNames,attr" yaml:"typeNames"` + SrsName *string `xml:"srsName,attr" yaml:"srsName"` Filter *Filter `xml:"Filter" yaml:"filter"` - SortBy *SortBy `xml:"SortBy" yaml:"sortby"` - PropertyName *[]string `xml:"PropertyName" yaml:"propertyname"` + SortBy *SortBy `xml:"SortBy" yaml:"sortBy"` + PropertyName *[]string `xml:"PropertyName" yaml:"propertyName"` } func (q *Query) parseKVPRequest(fpv getFeatureRequestParameterValue) []wsc110.Exception { @@ -364,7 +363,7 @@ type Filter struct { AND *AND `xml:"AND" yaml:"and"` OR *OR `xml:"OR" yaml:"or"` NOT *NOT `xml:"NOT" yaml:"not"` - ResourceID *ResourceIDs `xml:"ResourceId" yaml:"resourceid"` + ResourceID *ResourceIDs `xml:"ResourceId" yaml:"resourceId"` ComparisonOperator SpatialOperator } @@ -442,21 +441,21 @@ type ResourceID struct { // ComparisonOperator struct for Filter type ComparisonOperator struct { - PropertyIsEqualTo *[]PropertyIsEqualTo `xml:"PropertyIsEqualTo" yaml:"propertyisequalto"` - PropertyIsNotEqualTo *[]PropertyIsNotEqualTo `xml:"PropertyIsNotEqualTo" yaml:"propertyisnotequalto"` - PropertyIsLessThan *[]PropertyIsLessThan `xml:"PropertyIsLessThan" yaml:"propertyislessthan"` - PropertyIsGreaterThan *[]PropertyIsGreaterThan `xml:"PropertyIsGreaterThan" yaml:"propertyisgreaterthan"` - PropertyIsLessThanOrEqualTo *[]PropertyIsLessThanOrEqualTo `xml:"PropertyIsLessThanOrEqualTo" yaml:"propertyislessthanorequalto"` - PropertyIsGreaterThanOrEqualTo *[]PropertyIsGreaterThanOrEqualTo `xml:"PropertyIsGreaterThanOrEqualTo" yaml:"propertyisgreaterthanorequalto"` - PropertyIsBetween *[]PropertyIsBetween `xml:"PropertyIsBetween" yaml:"propertyisbetween"` - PropertyIsLike *[]PropertyIsLike `xml:"PropertyIsLike" yaml:"propertyislike"` + PropertyIsEqualTo *[]PropertyIsEqualTo `xml:"PropertyIsEqualTo" yaml:"propertyIsEqualTo"` + PropertyIsNotEqualTo *[]PropertyIsNotEqualTo `xml:"PropertyIsNotEqualTo" yaml:"propertyIsNotEqualTo"` + PropertyIsLessThan *[]PropertyIsLessThan `xml:"PropertyIsLessThan" yaml:"propertyIsLessThan"` + PropertyIsGreaterThan *[]PropertyIsGreaterThan `xml:"PropertyIsGreaterThan" yaml:"propertyIsGreaterThan"` + PropertyIsLessThanOrEqualTo *[]PropertyIsLessThanOrEqualTo `xml:"PropertyIsLessThanOrEqualTo" yaml:"propertyIsLessThanOrEqualTo"` + PropertyIsGreaterThanOrEqualTo *[]PropertyIsGreaterThanOrEqualTo `xml:"PropertyIsGreaterThanOrEqualTo" yaml:"propertyIsGreaterThanOrEqualTo"` + PropertyIsBetween *[]PropertyIsBetween `xml:"PropertyIsBetween" yaml:"propertyIsBetween"` + PropertyIsLike *[]PropertyIsLike `xml:"PropertyIsLike" yaml:"propertyIsLike"` } // ComparisonOperatorAttribute struct for the ComparisonOperators type ComparisonOperatorAttribute struct { - MatchCase *string `xml:"matchCase,attr" yaml:"matchcase"` - PropertyName *string `xml:"PropertyName" yaml:"propertyname"` // property i.e: id - ValueReference *string `xml:"ValueReference" yaml:"valuereference"` // path to a property i.e: the/path/to/a/id/in/a/document or just a id ... + MatchCase *string `xml:"matchCase,attr" yaml:"matchCase"` + PropertyName *string `xml:"PropertyName" yaml:"propertyName"` // property i.e: id + ValueReference *string `xml:"ValueReference" yaml:"valueReference"` // path to a property i.e: the/path/to/a/id/in/a/document or just a id ... Literal string `xml:"Literal" yaml:"literal"` } @@ -494,38 +493,38 @@ type PropertyIsGreaterThanOrEqualTo struct { // wildcard='*' singleChar='.' escape='!'> type PropertyIsLike struct { Wildcard string `xml:"wildcard,attr" yaml:"wildcard"` - SingleChar string `xml:"singleChar,attr" yaml:"singlechar"` + SingleChar string `xml:"singleChar,attr" yaml:"singleChar"` Escape string `xml:"escape,attr" yaml:"escape"` ComparisonOperatorAttribute } // PropertyIsBetween for ComparisonOperator type PropertyIsBetween struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` - LowerBoundary string `xml:"LowerBoundary" yaml:"lowerboundary"` - UpperBoundary string `xml:"UpperBoundary" yaml:"upperboundary"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` + LowerBoundary string `xml:"LowerBoundary" yaml:"lowerBoundary"` + UpperBoundary string `xml:"UpperBoundary" yaml:"upperBoundary"` } // GeometryOperand struct for Filter type GeometryOperand struct { Point *Point `xml:"Point" yaml:"point"` - MultiPoint *MultiPoint `xml:"MultiPoint" yaml:"multipoint"` - LineString *LineString `xml:"LineString" yaml:"linestring"` - MultiLineString *MultiLineString `xml:"MultiLineString" yaml:"multiLinestring"` + MultiPoint *MultiPoint `xml:"MultiPoint" yaml:"multiPoint"` + LineString *LineString `xml:"LineString" yaml:"lineString"` + MultiLineString *MultiLineString `xml:"MultiLineString" yaml:"multiLineString"` Curve *Curve `xml:"Curve" yaml:"curve"` - MultiCurve *MultiCurve `xml:"MultiCurve" yaml:"multicurve"` + MultiCurve *MultiCurve `xml:"MultiCurve" yaml:"multiCurve"` Polygon *Polygon `xml:"Polygon" yaml:"polygon"` - MultiPolygon *MultiPolygon `xml:"MultiPolygon" yaml:"multipolygon"` + MultiPolygon *MultiPolygon `xml:"MultiPolygon" yaml:"multiPolygon"` Surface *Surface `xml:"Surface" yaml:"surface"` - MultiSurface *MultiSurface `xml:"MultiSurface" yaml:"multisurface"` + MultiSurface *MultiSurface `xml:"MultiSurface" yaml:"multiSurface"` Box *Box `xml:"Box" yaml:"box"` Envelope *Envelope `xml:"Envelope" yaml:"envelope"` } // Geometry struct for GeometryOperand geometries type Geometry struct { - SrsName string `xml:"srsName,attr" yaml:"srsname"` - Content string `xml:",innerxml"` + SrsName string `xml:"srsName,attr" yaml:"srsName"` + Content string `xml:",innerxml" yaml:"content"` } // Point struct for GeometryOperand @@ -585,8 +584,8 @@ type Box struct { // Envelope struct for GeometryOperand type Envelope struct { - LowerCorner wsc110.Position `xml:"lowerCorner" yaml:"lowercorner"` - UpperCorner wsc110.Position `xml:"upperCorner" yaml:"uppercorner"` + LowerCorner wsc110.Position `xml:"lowerCorner" yaml:"lowerCorner"` + UpperCorner wsc110.Position `xml:"upperCorner" yaml:"upperCorner"` } // SpatialOperator struct for Filter @@ -599,62 +598,62 @@ type SpatialOperator struct { Crosses *Crosses `xml:"Crosses" yaml:"crosses"` Intersects *Intersects `xml:"Intersects" yaml:"intersects"` Contains *Contains `xml:"Contains" yaml:"contains"` - DWithin *DWithin `xml:"DWithin" yaml:"dwithin"` + DWithin *DWithin `xml:"DWithin" yaml:"dWithin"` Beyond *Beyond `xml:"Beyond" yaml:"beyond"` BBOX *GEOBBOX `xml:"BBOX" yaml:"bbox"` } // Equals for SpatialOperator type Equals struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Disjoint for SpatialOperator type Disjoint struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Touches for SpatialOperator type Touches struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Within for SpatialOperator type Within struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Overlaps for SpatialOperator type Overlaps struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Crosses for SpatialOperator type Crosses struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Intersects for SpatialOperator type Intersects struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // Contains for SpatialOperator type Contains struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand } // DWithin for SpatialOperator type DWithin struct { - PropertyName string `xml:"PropertyName" yaml:"propertyname"` + PropertyName string `xml:"PropertyName" yaml:"propertyName"` GeometryOperand Distance Distance `xml:"Distance" yaml:"distance"` } @@ -669,14 +668,14 @@ type Beyond struct { // Distance for DWithin and Beyond type Distance struct { Units string `xml:"units,attr" yaml:"unit"` - Text string `xml:",chardata"` + Text string `xml:",chardata" yaml:"text"` } // GEOBBOX for SpatialOperator type GEOBBOX struct { Units *string `xml:"unit,attr" yaml:"unit"` // unit or units.. - SrsName *string `xml:"srsName,attr" yaml:"srsname"` - ValueReference *string `xml:"ValueReference" yaml:"valuereference"` + SrsName *string `xml:"srsName,attr" yaml:"srsName"` + ValueReference *string `xml:"ValueReference" yaml:"valueReference"` Envelope Envelope `xml:"Envelope" yaml:"envelope"` // Text string `xml:",chardata"` // @@ -755,8 +754,8 @@ func (s SortBy) toString() string { // SortProperty for SortBy type SortProperty struct { - ValueReference string `xml:"ValueReference" yaml:"valuereference"` - SortOrder *string `xml:"SortOrder" yaml:"sortorder"` // ASC,DESC + ValueReference string `xml:"ValueReference" yaml:"valueReference"` + SortOrder *string `xml:"SortOrder" yaml:"sortOrder"` // ASC,DESC } // ProjectionClause based on Table 9 WFS2.0.0 spec diff --git a/pkg/wfs200/getfeature_request_pv.go b/pkg/wfs200/getfeature_request_pv.go index 42413f1..9ef7083 100644 --- a/pkg/wfs200/getfeature_request_pv.go +++ b/pkg/wfs200/getfeature_request_pv.go @@ -175,8 +175,8 @@ func (fpv *getFeatureRequestParameterValue) parseGetFeatureRequest(f GetFeatureR fpv.version = Version fpv.service = Service - if f.Startindex != nil { - i := strconv.Itoa(*f.Startindex) + if f.StartIndex != nil { + i := strconv.Itoa(*f.StartIndex) if fpv.standardPresentationParameters != nil { fpv.standardPresentationParameters.startindex = &i } else { diff --git a/pkg/wfs200/getfeature_test.go b/pkg/wfs200/getfeature_test.go index 5358a62..900fd47 100644 --- a/pkg/wfs200/getfeature_test.go +++ b/pkg/wfs200/getfeature_test.go @@ -33,7 +33,7 @@ func TestGetFeatureToXML(t *testing.T) { StandardPresentationParameters: StandardPresentationParameters{ OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), - Startindex: ip(0)}, + StartIndex: ip(0)}, BaseRequest: BaseRequest{ Service: Service, Version: Version}, @@ -50,7 +50,7 @@ func TestGetFeatureToXML(t *testing.T) { StandardPresentationParameters: StandardPresentationParameters{ OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), - Startindex: ip(0), + StartIndex: ip(0), }, BaseRequest: BaseRequest{ Attr: utils.XMLAttribute{ @@ -90,7 +90,7 @@ func TestGetFeatureParseXML(t *testing.T) { 0: {body: []byte(` `), - result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), Startindex: ip(0)}, + result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), StartIndex: ip(0)}, BaseRequest: BaseRequest{Service: "WFS", Version: "2.0.0"}}}, // Get feature by resourceid 1: {body: []byte(` @@ -101,7 +101,7 @@ func TestGetFeatureParseXML(t *testing.T) { `), - result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), Startindex: ip(0)}, + result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), StartIndex: ip(0)}, Query: Query{Filter: &Filter{ ResourceID: &ResourceIDs{{Rid: "kadastralegrens.29316bf0-b87f-4e8d-bf00-21f894bdf655"}}}}, BaseRequest: BaseRequest{ @@ -121,7 +121,7 @@ func TestGetFeatureParseXML(t *testing.T) { `), - result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), Startindex: ip(0)}, + result: GetFeatureRequest{XMLName: xml.Name{Local: "GetFeature"}, StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/gml+xml; version=3.2"), Count: ip(3), StartIndex: ip(0)}, Query: Query{Filter: &Filter{ ComparisonOperator: ComparisonOperator{PropertyIsEqualTo: &[]PropertyIsEqualTo{{ ComparisonOperatorAttribute: ComparisonOperatorAttribute{MatchCase: sp("true"), ValueReference: sp("id"), Literal: "29316bf0-b87f-4e8d-bf00-21f894bdf655"}, @@ -264,12 +264,12 @@ func TestGetFeatureParseQueryParameters(t *testing.T) { {Name: xml.Name{Space: "xmlns", Local: "ns2"}, Value: "http://someserver.com/ns2"}}, }, Query: Query{TypeNames: "dummy"}}}, - // Startindex & resulttype + // StartIndex & resulttype 3: {queryParams: map[string][]string{OUTPUTFORMAT: {"application/xml"}, STARTINDEX: {"1000"}, RESULTTYPE: {"hits"}, TYPENAMES: {"dummy"}, COUNT: {"3"}, VERSION: {Version}}, result: GetFeatureRequest{ StandardPresentationParameters: StandardPresentationParameters{OutputFormat: sp("application/xml"), Count: ip(3), - Startindex: ip(1000), ResultType: sp("hits"), + StartIndex: ip(1000), ResultType: sp("hits"), }, XMLName: xml.Name{Local: getfeature}, BaseRequest: BaseRequest{Service: Service, Version: Version}, Query: Query{TypeNames: "dummy"}}, @@ -347,9 +347,9 @@ func compareGetFeatureQuery(result, expected GetFeatureRequest, tid int, t *test t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, expected.OutputFormat, result.OutputFormat) } } - if expected.Startindex != nil { - if *result.Startindex != *expected.Startindex { - t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, expected.Startindex, result.Startindex) + if expected.StartIndex != nil { + if *result.StartIndex != *expected.StartIndex { + t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, expected.StartIndex, result.StartIndex) } } if expected.ResultType != nil { @@ -460,7 +460,7 @@ func TestGetFeatureToQueryParameters(t *testing.T) { expectedquery: map[string][]string{REQUEST: {getfeature}, SERVICE: {Service}, VERSION: {Version}, TYPENAMES: {`ns1:F1`}}}, 1: {getfeature: GetFeatureRequest{XMLName: xml.Name{Local: getfeature}, BaseRequest: BaseRequest{Service: Service, Version: Version}, - StandardPresentationParameters: StandardPresentationParameters{Startindex: ip(100), Count: ip(21)}, + StandardPresentationParameters: StandardPresentationParameters{StartIndex: ip(100), Count: ip(21)}, Query: Query{ TypeNames: `ns1:F1`, Filter: &Filter{ResourceID: &ResourceIDs{{Rid: "one"}, {Rid: "two"}}}}, diff --git a/pkg/wms130/boundingbox.go b/pkg/wms130/boundingbox.go index 2f1e991..b76e2c9 100644 --- a/pkg/wms130/boundingbox.go +++ b/pkg/wms130/boundingbox.go @@ -10,8 +10,8 @@ import ( type BoundingBox struct { Crs string `xml:"crs,attr,omitempty" yaml:"crs,omitempty"` Dimensions string `xml:"dimensions,attr,omitempty" yaml:"dimensions,omitempty"` - LowerCorner Position `xml:"LowerCorner" yaml:"lowercorner"` - UpperCorner Position `xml:"UpperCorner" yaml:"uppercorner"` + LowerCorner Position `xml:"LowerCorner" yaml:"lowerCorner"` + UpperCorner Position `xml:"UpperCorner" yaml:"upperCorner"` } // Position type @@ -22,7 +22,7 @@ func (b *BoundingBox) ToQueryParameters() string { return fmt.Sprintf("%f,%f,%f,%f", b.LowerCorner[0], b.LowerCorner[1], b.UpperCorner[0], b.UpperCorner[1]) } -//ParseString builds a BoundingBox based on a string +// ParseString builds a BoundingBox based on a string func (b *BoundingBox) parseString(boundingbox string) Exceptions { result := strings.Split(boundingbox, ",") var lx, ly, ux, uy float64 diff --git a/pkg/wms130/boundingbox_yaml.go b/pkg/wms130/boundingbox_yaml.go new file mode 100644 index 0000000..3c5faa6 --- /dev/null +++ b/pkg/wms130/boundingbox_yaml.go @@ -0,0 +1,24 @@ +package wms130 + +import ( + "fmt" + "strconv" +) + +// UnmarshalYAML Position +func (p *Position) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + + position := getPositionFromString(s) + *p = Position{position[0], position[1]} + + return nil +} + +// MarshalYAML Position +func (p Position) MarshalYAML() (interface{}, error) { + return fmt.Sprintf("%s %s", strconv.FormatFloat(p[0], 'f', -1, 64), strconv.FormatFloat(p[1], 'f', -1, 64)), nil +} diff --git a/pkg/wms130/boundingbox_yaml_test.go b/pkg/wms130/boundingbox_yaml_test.go new file mode 100644 index 0000000..8434698 --- /dev/null +++ b/pkg/wms130/boundingbox_yaml_test.go @@ -0,0 +1,52 @@ +package wms130 + +import ( + "testing" + + "gopkg.in/yaml.v3" +) + +func TestUnmarshalYAMLPosition(t *testing.T) { + + var tests = []struct { + positionstring []byte + expectedposition Position + }{ + 0: {positionstring: []byte(`2.52712538742158 50.2128625669452`), expectedposition: Position{2.52712538742158, 50.2128625669452}}, + 1: {positionstring: []byte(`7.37402550506231 55.7211602557705`), expectedposition: Position{7.37402550506231, 55.7211602557705}}, + 2: {positionstring: []byte(`7.37402550506231 55.7211602557705 0 1 2 3`), expectedposition: Position{7.37402550506231, 55.7211602557705}}, + } + + for k, test := range tests { + var pos Position + err := yaml.Unmarshal(test.positionstring, &pos) + if err != nil { + t.Errorf("test: %d, yaml.UnMarshal failed with '%s'\n", k, err) + } else { + if pos != test.expectedposition { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedposition, pos) + } + } + } +} + +func TestMarshalYAMLPosition(t *testing.T) { + var tests = []struct { + positionstring []byte + position Position + }{ + 0: {positionstring: []byte("2.52712538742158 50.2128625669452\n"), position: Position{2.52712538742158, 50.2128625669452}}, + 1: {positionstring: []byte("7.37402550506231 55.7211602557705\n"), position: Position{7.37402550506231, 55.7211602557705}}, + } + + for k, test := range tests { + pos, err := yaml.Marshal(test.position) + if err != nil { + t.Errorf("test: %d, yaml.Marshal failed with '%s'\n", k, err) + } else { + if string(pos) != string(test.positionstring) { + t.Errorf("test: %d, expected: %s,\n got: %s", k, test.positionstring, pos) + } + } + } +} diff --git a/pkg/wms130/capabilities.go b/pkg/wms130/capabilities.go index 528266d..b500819 100644 --- a/pkg/wms130/capabilities.go +++ b/pkg/wms130/capabilities.go @@ -27,30 +27,30 @@ func (c *Capabilities) ParseYAML(doc []byte) error { // Capabilities struct needed for keeping all constraints and capabilities together type Capabilities struct { - WMSCapabilities `xml:"WMSCapabilities" yaml:"wmscapabilities"` - OptionalConstraints `xml:"OptionalConstraints" yaml:"optionalconstraints"` + WMSCapabilities `xml:"WMSCapabilities" yaml:"wmsCapabilities"` + *OptionalConstraints `xml:"OptionalConstraints" yaml:"optionalConstraints,omitempty"` } // WMSCapabilities base struct type WMSCapabilities struct { Request Request `xml:"Request" yaml:"request"` Exception ExceptionType `xml:"Exception" yaml:"exception"` - ExtendedCapabilities *ExtendedCapabilities `xml:"inspire_vs:ExtendedCapabilities" yaml:"extendedcapabilities"` + ExtendedCapabilities *ExtendedCapabilities `xml:"inspire_vs:ExtendedCapabilities" yaml:"extendedCapabilities,omitempty"` Layer []Layer `xml:"Layer" yaml:"layer"` } // OptionalConstraints struct type OptionalConstraints struct { - LayerLimit int `xml:"LayerLimit,omitempty" yaml:"layerlimit,omitempty"` - MaxWidth int `xml:"MaxWidth,omitempty" yaml:"maxwidth,omitempty"` - MaxHeight int `xml:"MaxHeight,omitempty" yaml:"maxheight,omitempty"` + LayerLimit int `xml:"LayerLimit,omitempty" yaml:"layerLimit,omitempty"` + MaxWidth int `xml:"MaxWidth,omitempty" yaml:"maxWidth,omitempty"` + MaxHeight int `xml:"MaxHeight,omitempty" yaml:"maxHeight,omitempty"` } // Request struct with the different operations, should be filled from the template type Request struct { - GetCapabilities RequestType `xml:"GetCapabilities" yaml:"getcapabilities"` - GetMap RequestType `xml:"GetMap" yaml:"getmap"` - GetFeatureInfo *RequestType `xml:"GetFeatureInfo" yaml:"getfeatureinfo"` + GetCapabilities RequestType `xml:"GetCapabilities" yaml:"getCapabilities"` + GetMap RequestType `xml:"GetMap" yaml:"getMap"` + GetFeatureInfo *RequestType `xml:"GetFeatureInfo" yaml:"getFeatureInfo"` } // ExceptionType struct containing the different available exceptions, should be filled from the template @@ -64,27 +64,27 @@ type ExceptionType struct { type Layer struct { Queryable *int `xml:"queryable,attr" yaml:"queryable"` // layer has a full/complete map coverage - Opaque *string `xml:"opaque,attr" yaml:"opaque"` + Opaque *string `xml:"opaque,attr" yaml:"opaque,omitempty"` // no cascaded attr in Layer element, because we don't do cascaded services e.g. wms services "proxying" and/or combining other wms services //Cascaded *string `xml:"cascaded,attr" yaml:"cascaded"` - Name *string `xml:"Name" yaml:"name"` + Name *string `xml:"Name" yaml:"name,omitempty"` Title string `xml:"Title" yaml:"title"` - Abstract string `xml:"Abstract,omitempty" yaml:"abstract,omitempty"` - KeywordList *Keywords `xml:"KeywordList" yaml:"keywordlist"` - CRS []CRS `xml:"CRS" yaml:"crs"` - EXGeographicBoundingBox *EXGeographicBoundingBox `xml:"EX_GeographicBoundingBox" yaml:"exgeographicboundingbox"` - BoundingBox []*LayerBoundingBox `xml:"BoundingBox" yaml:"boundingbox"` - Dimension []*Dimension `xml:"Dimension" yaml:"dimension"` - Attribution *Attribution `xml:"Attribution,omitempty" yaml:"attribution"` - AuthorityURL *AuthorityURL `xml:"AuthorityURL" yaml:"authorityurl"` - Identifier *Identifier `xml:"Identifier" yaml:"identifier"` - MetadataURL []*MetadataURL `xml:"MetadataURL" yaml:"metadataurl"` - DataURL *URL `xml:"DataURL,omitempty" yaml:"dataurl"` - FeatureListURL *URL `xml:"FeatureListURL,omitempty" yaml:"featurelisturl"` - Style []*Style `xml:"Style" yaml:"style"` - MinScaleDenominator *float64 `xml:"MinScaleDenominator,omitempty" yaml:"minscaledenominator"` - MaxScaleDenominator *float64 `xml:"MaxScaleDenominator,omitempty" yaml:"maxscaledenominator"` - Layer []*Layer `xml:"Layer" yaml:"layer"` + Abstract *string `xml:"Abstract,omitempty" yaml:"abstract,omitempty"` + KeywordList *Keywords `xml:"KeywordList" yaml:"keywordList,omitempty"` + CRS []CRS `xml:"CRS" yaml:"crs,omitempty"` + EXGeographicBoundingBox *EXGeographicBoundingBox `xml:"EX_GeographicBoundingBox" yaml:"exGeographicBoundingBox,omitempty"` + BoundingBox []*LayerBoundingBox `xml:"BoundingBox" yaml:"boundingBox,omitempty"` + Dimension []*Dimension `xml:"Dimension" yaml:"dimension,omitempty"` + Attribution *Attribution `xml:"Attribution,omitempty" yaml:"attribution,omitempty"` + AuthorityURL *AuthorityURL `xml:"AuthorityURL" yaml:"authorityUrl,omitempty"` + Identifier *Identifier `xml:"Identifier" yaml:"identifier,omitempty"` + MetadataURL []*MetadataURL `xml:"MetadataURL" yaml:"metadataUrl,omitempty"` + DataURL *URL `xml:"DataURL,omitempty" yaml:"dataUrl,omitempty"` + FeatureListURL *URL `xml:"FeatureListURL,omitempty" yaml:"featureListUrl,omitempty"` + Style []*Style `xml:"Style" yaml:"style,omitempty"` + MinScaleDenominator *float64 `xml:"MinScaleDenominator,omitempty" yaml:"minScaleDenominator,omitempty"` + MaxScaleDenominator *float64 `xml:"MaxScaleDenominator,omitempty" yaml:"maxScaleDenominator,omitempty"` + Layer []*Layer `xml:"Layer" yaml:"layer,omitempty"` } // StyleDefined checks if the style that is defined is available for the requested layer @@ -214,7 +214,7 @@ func (c *Capabilities) GetLayer(layername string) (Layer, Exceptions) { // RequestType containing the formats and DCPTypes available type RequestType struct { Format []string `xml:"Format" yaml:"format"` - DCPType *DCPType `xml:"DCPType" yaml:"dcptype"` + DCPType *DCPType `xml:"DCPType" yaml:"dcpType"` } // Identifier in struct for repeatability @@ -225,58 +225,66 @@ type Identifier struct { // Attribution in struct for repeatability type Attribution struct { - Title string `xml:"Title" yaml:"title"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` - LogoURL struct { - Format *string `xml:"Format" yaml:"format"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` - } `xml:"LogoURL" yaml:"logourl"` + Title *string `xml:"Title" yaml:"title"` + OnlineResource *OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` + LogoURL *LogoURL `xml:"LogoURL" yaml:"logoUrl"` } -// Identifier in struct for repeatability +// LogoURL in struct for repeatability +type LogoURL struct { + Format *string `xml:"Format" yaml:"format"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` +} + +// URL in struct for repeatability type URL struct { Format *string `xml:"Format" yaml:"format"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` } // MetadataURL in struct for repeatability type MetadataURL struct { Type *string `xml:"type,attr" yaml:"type"` Format *string `xml:"Format" yaml:"format"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` } // AuthorityURL in struct for repeatability type AuthorityURL struct { Name string `xml:"name,attr" yaml:"name"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` } // ExtendedCapabilities containing the inspire extendedcapabilities, when available type ExtendedCapabilities struct { - MetadataURL struct { - URL string `xml:"inspire_common:URL" yaml:"url"` - MediaType string `xml:"inspire_common:MediaType" yaml:"mediatype"` - } `xml:"inspire_common:MetadataUrl" yaml:"metadataurl"` - SupportedLanguages struct { - DefaultLanguage struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:DefaultLanguage" yaml:"defaultlanguage"` - SupportedLanguage *[]struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:SupportedLanguage" yaml:"supportedlanguage"` - } `xml:"inspire_common:SupportedLanguages" yaml:"supportedlanguages"` - ResponseLanguage struct { - Language string `xml:"inspire_common:Language" yaml:"language"` - } `xml:"inspire_common:ResponseLanguage" yaml:"responselanguage"` + MetadataURL ExtendedMetadataURL `xml:"inspire_common:MetadataUrl" yaml:"metadataUrl"` + SupportedLanguages SupportedLanguages `xml:"inspire_common:SupportedLanguages" yaml:"supportedLanguages"` + ResponseLanguage Language `xml:"inspire_common:ResponseLanguage" yaml:"responseLanguage"` +} + +// ExtendedMetadataURL struct for the WMS 1.3.0 +type ExtendedMetadataURL struct { + URL string `xml:"inspire_common:URL" yaml:"url"` + MediaType string `xml:"inspire_common:MediaType" yaml:"mediaType"` +} + +// SupportedLanguages struct for the WMS 1.3.0 +type SupportedLanguages struct { + DefaultLanguage Language `xml:"inspire_common:DefaultLanguage" yaml:"defaultLanguage"` + SupportedLanguage *[]Language `xml:"inspire_common:SupportedLanguage" yaml:"supportedLanguage"` +} + +// Language struct for the WMS 1.3.0 +type Language struct { + Language string `xml:"inspire_common:Language" yaml:"language"` } // EXGeographicBoundingBox in struct for repeatability type EXGeographicBoundingBox struct { - WestBoundLongitude float64 `xml:"westBoundLongitude" yaml:"westboundlongitude"` - EastBoundLongitude float64 `xml:"eastBoundLongitude" yaml:"eastboundlongitude"` - SouthBoundLatitude float64 `xml:"southBoundLatitude" yaml:"southboundlatitude"` - NorthBoundLatitude float64 `xml:"northBoundLatitude" yaml:"northboundlatitude"` + WestBoundLongitude float64 `xml:"westBoundLongitude" yaml:"westBoundLongitude"` + EastBoundLongitude float64 `xml:"eastBoundLongitude" yaml:"eastBoundLongitude"` + SouthBoundLatitude float64 `xml:"southBoundLatitude" yaml:"southBoundLatitude"` + NorthBoundLatitude float64 `xml:"northBoundLatitude" yaml:"northBoundLatitude"` } // LayerBoundingBox in struct for repeatability @@ -292,32 +300,38 @@ type LayerBoundingBox struct { // Style in struct for repeatability type Style struct { - Name string `xml:"Name" yaml:"name"` - Title string `xml:"Title" yaml:"title"` - Abstract string `xml:"Abstract,omitempty" yaml:"abstract"` - LegendURL *struct { - Width int `xml:"width,attr" yaml:"width"` - Height int `xml:"height,attr" yaml:"height"` - Format string `xml:"Format" yaml:"format"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` - } `xml:"LegendURL" yaml:"legendurl"` - StyleSheetURL *struct { - Format string `xml:"Format" yaml:"format"` - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` - } `xml:"StyleSheetURL,omitempty" yaml:"stylesheeturl"` + Name string `xml:"Name" yaml:"name"` + Title string `xml:"Title" yaml:"title"` + Abstract *string `xml:"Abstract,omitempty" yaml:"abstract,omitempty"` + LegendURL *LegendURL `xml:"LegendURL" yaml:"legendUrl"` + StyleSheetURL *StyleSheetURL `xml:"StyleSheetURL,omitempty" yaml:"styleSheetUrl,omitempty"` +} + +// LegendURL struct for the WMS 1.3.0 +type LegendURL struct { + Width int `xml:"width,attr" yaml:"width"` + Height int `xml:"height,attr" yaml:"height"` + Format string `xml:"Format" yaml:"format"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` +} + +// StyleSheetURL struct for the WMS 1.3.0 +type StyleSheetURL struct { + Format string `xml:"Format" yaml:"format"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` } // DCPType in struct for repeatability type DCPType struct { HTTP struct { - Get *Method `xml:"Get" yaml:"get"` + Get Method `xml:"Get" yaml:"get"` Post *Method `xml:"Post" yaml:"post"` } `xml:"HTTP" yaml:"http"` } // Method in struct for repeatability type Method struct { - OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineresource"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` } // OnlineResource in struct for repeatability @@ -330,7 +344,7 @@ type OnlineResource struct { type Dimension struct { Name *string `xml:"name,attr" yaml:"name"` Units *string `xml:"units,attr" yaml:"units"` - Default *string `xml:"default,attr,omitempty" yaml:"default"` - NearestValue *string `xml:"nearestValue,attr,omitempty" yaml:"nearestvalue"` + Default *string `xml:"default,attr,omitempty" yaml:"default,omitempty"` + NearestValue *string `xml:"nearestValue,attr,omitempty" yaml:"nearestValue,omitempty"` Value *string `xml:",chardata" yaml:"value"` } diff --git a/pkg/wms130/common.go b/pkg/wms130/common.go index c9a4a99..311980c 100644 --- a/pkg/wms130/common.go +++ b/pkg/wms130/common.go @@ -6,7 +6,6 @@ import ( "github.com/pdok/ogc-specifications/pkg/utils" ) -// const ( getcapabilities = `GetCapabilities` getmap = `GetMap` @@ -35,7 +34,7 @@ type baseParameterValueRequest struct { type BaseRequest struct { Service string `xml:"service,attr" yaml:"service,omitempty"` Version string `xml:"version,attr" yaml:"version"` - Attr utils.XMLAttribute `xml:",attr"` + Attr utils.XMLAttribute `xml:",attr" yaml:"attr"` } // ParseQueryParameters builds a BaseRequest struct based on the given parameters diff --git a/pkg/wms130/crs_yaml.go b/pkg/wms130/crs_yaml.go index 28b9433..2100c0c 100644 --- a/pkg/wms130/crs_yaml.go +++ b/pkg/wms130/crs_yaml.go @@ -14,3 +14,7 @@ func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } + +func (c CRS) MarshalYAML() (interface{}, error) { + return c.String(), nil +} diff --git a/pkg/wms130/exception.go b/pkg/wms130/exception.go index e452ec8..04f4655 100644 --- a/pkg/wms130/exception.go +++ b/pkg/wms130/exception.go @@ -2,13 +2,12 @@ package wms130 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" ) // exception type exception struct { - ExceptionText string `xml:",chardata" yaml:"exception"` - ExceptionCode string `xml:"code,attr" yaml:"code"` - LocatorCode string `xml:"locator,attr,omitempty" yaml:"locator,omitempty"` + common.ExceptionDetails } // Exceptions is a array of the Exception interface @@ -16,12 +15,12 @@ type Exceptions []exception // ServiceExceptionReport struct type ServiceExceptionReport struct { - XMLName xml.Name `xml:"ServiceExceptionReport" yaml:"serviceexceptionreport"` + XMLName xml.Name `xml:"ServiceExceptionReport" yaml:"serviceExceptionReport"` Version string `xml:"version,attr" yaml:"version"` - Xmlns string `xml:"xmlns,attr,omitempty"` - Xsi string `xml:"xsi,attr,omitempty"` - SchemaLocation string `xml:"schemaLocation,attr,omitempty"` - ServiceException Exceptions `xml:"ServiceException"` + Xmlns string `xml:"xmlns,attr,omitempty" yaml:"xmlns"` + Xsi string `xml:"xsi,attr,omitempty" yaml:"xsi"` + SchemaLocation string `xml:"schemaLocation,attr,omitempty" yaml:"schemaLocation"` + ServiceException Exceptions `xml:"ServiceException" yaml:"serviceException"` } // ToReport builds a ServiceExceptionReport from an array of Exceptions diff --git a/pkg/wms130/exception_codes.go b/pkg/wms130/exception_codes.go index e620856..23bfdb6 100644 --- a/pkg/wms130/exception_codes.go +++ b/pkg/wms130/exception_codes.go @@ -2,113 +2,114 @@ package wms130 import ( "fmt" + "github.com/pdok/ogc-specifications/pkg/common" ) // InvalidFormat exception func InvalidFormat(unknownformat string) exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The format: %s, is a invalid image format", unknownformat), ExceptionCode: `InvalidFormat`, - } + }} } // InvalidCRS exception func InvalidCRS(s ...string) exception { if len(s) == 1 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("CRS is not known by this service: %s", s[0]), ExceptionCode: `InvalidCRS`, - } + }} } if len(s) == 2 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The CRS: %s is not known by the layer: %s", s[0], s[1]), ExceptionCode: `InvalidCRS`, - } + }} } - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidCRS`, - } + }} } // LayerNotDefined exception func LayerNotDefined(s ...string) exception { if len(s) == 1 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The layer: %s is not known by the server", s[0]), ExceptionCode: `LayerNotDefined`, - } + }} } - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `LayerNotDefined`, - } + }} } // StyleNotDefined exception func StyleNotDefined(s ...string) exception { if len(s) == 2 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The style: %s is not known by the server for the layer: %s", s[0], s[1]), ExceptionCode: `StyleNotDefined`, - } + }} } - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: `There is a one-to-one correspondence between the values in the LAYERS parameter and the values in the STYLES parameter. Expecting an empty string for the STYLES like STYLES= or comma-separated list STYLES=,,, or using keyword default STYLES=default,default,...`, ExceptionCode: `StyleNotDefined`, - } + }} } // LayerNotQueryable exception func LayerNotQueryable(s ...string) exception { if len(s) == 1 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("Layer: %s, can not be queried", s[0]), ExceptionCode: `LayerNotQueryable`, LocatorCode: s[0], - } + }} } - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `LayerNotQueryable`, - } + }} } // InvalidPoint exception // i and j are strings so we can return none integer values in the exception func InvalidPoint(i, j string) exception { // TODO provide giving WIDTH and HEIGHT values in Exception response - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The parameters I and J are invalid, given: %s for I and %s for J", i, j), ExceptionCode: `InvalidPoint`, - } + }} } // CurrentUpdateSequence exception func CurrentUpdateSequence() exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `CurrentUpdateSequence`, - } + }} } // InvalidUpdateSequence exception func InvalidUpdateSequence() exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidUpdateSequence`, - } + }} } // MissingDimensionValue exception func MissingDimensionValue() exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `MissingDimensionValue`, - } + }} } // InvalidDimensionValue exception func InvalidDimensionValue() exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidDimensionValue`, - } + }} } //////////////// @@ -117,37 +118,37 @@ func InvalidDimensionValue() exception { // MissingParameterValue exception func MissingParameterValue(s ...string) exception { if len(s) >= 2 { - return exception{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } - return exception{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} } // InvalidParameterValue exception func InvalidParameterValue(value, locator string) exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s contains a invalid value: %s", locator, value), LocatorCode: value, ExceptionCode: `InvalidParameterValue`, - } + }} } // NoApplicableCode exception func NoApplicableCode(message string) exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: message, ExceptionCode: `NoApplicableCode`, - } + }} } // OperationNotSupported exception func OperationNotSupported(message string) exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), ExceptionCode: `OperationNotSupported`, LocatorCode: message, - } + }} } diff --git a/pkg/wms130/exception_test.go b/pkg/wms130/exception_test.go index abdec19..d35a322 100644 --- a/pkg/wms130/exception_test.go +++ b/pkg/wms130/exception_test.go @@ -1,6 +1,7 @@ package wms130 import ( + "github.com/pdok/ogc-specifications/pkg/common" "testing" ) @@ -11,7 +12,7 @@ func TestWFSException(t *testing.T) { exceptionCode string locatorCode string }{ - 0: {exception: exception{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}, + 0: {exception: exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, exceptionText: "", exceptionCode: "", locatorCode: "", @@ -79,7 +80,7 @@ func TestReport(t *testing.T) { result []byte err error }{ - 0: {exceptions: Exceptions{exception{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, + 0: {exceptions: Exceptions{exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}}, result: []byte(` diff --git a/pkg/wms130/getcapabilities_request.go b/pkg/wms130/getcapabilities_request.go index 8c64797..b5ea330 100644 --- a/pkg/wms130/getcapabilities_request.go +++ b/pkg/wms130/getcapabilities_request.go @@ -11,7 +11,7 @@ import ( // GetCapabilitiesRequest struct with the needed parameters/attributes needed for making a GetCapabilities request type GetCapabilitiesRequest struct { - XMLName xml.Name `xml:"GetCapabilities" yaml:"getcapabilities"` + XMLName xml.Name `xml:"GetCapabilities" yaml:"getCapabilities"` BaseRequest } diff --git a/pkg/wms130/getcapabilities_response.go b/pkg/wms130/getcapabilities_response.go index 825b93e..ff55069 100644 --- a/pkg/wms130/getcapabilities_response.go +++ b/pkg/wms130/getcapabilities_response.go @@ -36,8 +36,8 @@ func (gc GetCapabilitiesResponse) ToXML() []byte { // GetCapabilitiesResponse base struct type GetCapabilitiesResponse struct { - XMLName xml.Name `xml:"WMS_Capabilities"` - Namespaces `yaml:"namespaces"` + XMLName xml.Name `xml:"WMS_Capabilities" yaml:"wmsCapabilities"` + *Namespaces `yaml:"namespaces,omitempty"` WMSService WMSService `xml:"Service" yaml:"service"` Capabilities Capabilities `xml:"Capability" yaml:"capability"` } @@ -48,42 +48,47 @@ type Namespaces struct { XmlnsSLD string `xml:"xmlns:sld,attr" yaml:"sld"` //http://www.opengis.net/sld XmlnsXlink string `xml:"xmlns:xlink,attr" yaml:"xlink"` //http://www.w3.org/1999/xlink XmlnsXSI string `xml:"xmlns:xsi,attr" yaml:"xsi"` //http://www.w3.org/2001/XMLSchema-instance - XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspirecommon,omitempty"` //http://inspire.ec.europa.eu/schemas/common/1.0 - XmlnsInspireVs string `xml:"xmlns:inspire_vs,attr,omitempty" yaml:"inspirevs,omitempty"` //http://inspire.ec.europa.eu/schemas/inspire_vs/1.0 + XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspireCommon,omitempty"` //http://inspire.ec.europa.eu/schemas/common/1.0 + XmlnsInspireVs string `xml:"xmlns:inspire_vs,attr,omitempty" yaml:"inspireVs,omitempty"` //http://inspire.ec.europa.eu/schemas/inspire_vs/1.0 Version string `xml:"version,attr" yaml:"version"` - SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemalocation"` + SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemaLocation"` } // WMSService struct containing the base service information filled from the template type WMSService struct { - Name string `xml:"Name" yaml:"name"` - Title string `xml:"Title" yaml:"title"` - Abstract string `xml:"Abstract" yaml:"abstract"` - KeywordList *Keywords `xml:"KeywordList" yaml:"keywordlist"` - OnlineResource struct { - Xlink *string `xml:"xmlns:xlink,attr" yaml:"xlink"` - Type *string `xml:"xlink:type,attr" yaml:"type"` - Href *string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"OnlineResource" yaml:"onlineresource"` - ContactInformation struct { - ContactPersonPrimary struct { - ContactPerson string `xml:"ContactPerson" yaml:"contactperson"` - ContactOrganization string `xml:"ContactOrganization" yaml:"contactorganization"` - } `xml:"ContactPersonPrimary" yaml:"contactpersonprimary"` - ContactPosition string `xml:"ContactPosition" yaml:"contactposition"` - ContactAddress struct { - AddressType string `xml:"AddressType" yaml:"addresstype"` - Address string `xml:"Address" yaml:"address"` - City string `xml:"City" yaml:"city"` - StateOrProvince string `xml:"StateOrProvince" yaml:"stateorprovince"` - PostCode string `xml:"PostCode" yaml:"postalcode"` - Country string `xml:"Country" yaml:"country"` - } `xml:"ContactAddress" yaml:"contactaddress"` - ContactVoiceTelephone string `xml:"ContactVoiceTelephone" yaml:"contactvoicetelephone"` - ContactFacsimileTelephone string `xml:"ContactFacsimileTelephone" yaml:"contactfacsimiletelephone"` - ContactElectronicMailAddress string `xml:"ContactElectronicMailAddress" yaml:"contactelectronicmailaddress"` - } `xml:"ContactInformation"` - Fees string `xml:"Fees" yaml:"fees"` - AccessConstraints string `xml:"AccessConstraints" yaml:"accessconstraints"` - OptionalConstraints + Name string `xml:"Name" yaml:"name"` + Title string `xml:"Title" yaml:"title"` + Abstract *string `xml:"Abstract" yaml:"abstract"` + KeywordList *Keywords `xml:"KeywordList" yaml:"keywordList"` + OnlineResource OnlineResource `xml:"OnlineResource" yaml:"onlineResource"` + ContactInformation *ContactInformation `xml:"ContactInformation" yaml:"contactInformation"` + Fees *string `xml:"Fees" yaml:"fees"` + AccessConstraints *string `xml:"AccessConstraints" yaml:"accessConstraints"` + *OptionalConstraints `yaml:"optionalConstraints,omitempty"` +} + +// ContactInformation struct containing the information about a contact person for the service +type ContactInformation struct { + ContactPersonPrimary *ContactPersonPrimary `xml:"ContactPersonPrimary" yaml:"contactPersonPrimary"` + ContactPosition *string `xml:"ContactPosition" yaml:"contactPosition"` + ContactAddress *ContactAddress `xml:"ContactAddress" yaml:"contactAddress"` + ContactVoiceTelephone *string `xml:"ContactVoiceTelephone" yaml:"contactVoiceTelephone"` + ContactFacsimileTelephone *string `xml:"ContactFacsimileTelephone" yaml:"contactFacsimileTelephone"` + ContactElectronicMailAddress *string `xml:"ContactElectronicMailAddress" yaml:"contactElectronicMailAddress"` +} + +// ContactPersonPrimary struct containing information for the person to contact +type ContactPersonPrimary struct { + ContactPerson string `xml:"ContactPerson" yaml:"contactPerson"` + ContactOrganization string `xml:"ContactOrganization" yaml:"contactOrganization"` +} + +// ContactAddress struct containing the address for the contact supplying the service +type ContactAddress struct { + AddressType string `xml:"AddressType" yaml:"addressType"` + Address string `xml:"Address" yaml:"address"` + City string `xml:"City" yaml:"city"` + StateOrProvince string `xml:"StateOrProvince" yaml:"stateOrProvince"` + PostalCode string `xml:"PostCode" yaml:"postalCode"` + Country string `xml:"Country" yaml:"country"` } diff --git a/pkg/wms130/getfeatureinfo_request.go b/pkg/wms130/getfeatureinfo_request.go index 3995d92..3631688 100644 --- a/pkg/wms130/getfeatureinfo_request.go +++ b/pkg/wms130/getfeatureinfo_request.go @@ -24,26 +24,26 @@ const ( // GetFeatureInfoRequest struct with the needed parameters/attributes needed for making a GetFeatureInfo request type GetFeatureInfoRequest struct { - XMLName xml.Name `xml:"GetFeatureInfo" yaml:"getfeatureinfo"` + XMLName xml.Name `xml:"GetFeatureInfo" yaml:"getFeatureInfo"` BaseRequest // // These are the 'minimum' required GetMap parameters // needed in a GetFeatureInfo request - StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledlayerdescriptor"` //TODO layers is need styles is not! + StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledLayerDescriptor"` //TODO layers is need styles is not! CRS string `xml:"CRS" yaml:"crs"` - BoundingBox BoundingBox `xml:"BoundingBox" yaml:"boundingbox"` + BoundingBox BoundingBox `xml:"BoundingBox" yaml:"boundingBox"` // We skip the Output struct, because these are not required parameters Size Size `xml:"Size" yaml:"size"` Format string `xml:"Format,omitempty" yaml:"format,omitempty"` - QueryLayers []string `xml:"QueryLayers" yaml:"querylayers"` + QueryLayers []string `xml:"QueryLayers" yaml:"queryLayers"` I int `xml:"I" yaml:"i"` J int `xml:"J" yaml:"j"` - InfoFormat string `xml:"InfoFormat" yaml:"infoformat" default:"text/plain"` // default text/plain + InfoFormat string `xml:"InfoFormat" yaml:"infoFormat" default:"text/plain"` // default text/plain // Optional Keys - FeatureCount *int `xml:"FeatureCount,omitempty" yaml:"featurecount,omitempty" default:"1"` // default 1 + FeatureCount *int `xml:"FeatureCount,omitempty" yaml:"featureCount,omitempty" default:"1"` // default 1 Exceptions *string `xml:"Exceptions" yaml:"exceptions"` } diff --git a/pkg/wms130/getfeatureinfo_request_pv.go b/pkg/wms130/getfeatureinfo_request_pv.go index fb4a36c..11de5ae 100644 --- a/pkg/wms130/getfeatureinfo_request_pv.go +++ b/pkg/wms130/getfeatureinfo_request_pv.go @@ -6,7 +6,7 @@ import ( "strings" ) -//getFeatureInfoRequestParameterValue struct +// getFeatureInfoRequestParameterValue struct type getFeatureInfoRequestParameterValue struct { // Table 8 - The Parameters of a GetFeatureInfo request service string `yaml:"service,omitempty"` @@ -132,14 +132,14 @@ func (ipv *getFeatureInfoRequestParameterValue) parseGetFeatureInfoRequest(i Get // GetFeatureInfoParameterValueMandatory struct containing the mandatory WMS request Parameter Value type getFeatureInfoParameterValueMandatory struct { - querylayers string `yaml:"query_layers,omitempty"` - infoformat string `yaml:"info_format,omitempty"` + querylayers string `yaml:"queryLayers,omitempty"` + infoformat string `yaml:"infoFormat,omitempty"` i string `yaml:"i,omitempty"` j string `yaml:"j,omitempty"` } // GetFeatureInfoParameterValueOptional struct containing the optional WMS request Parameter Value type getFeatureInfoParameterValueOptional struct { - featurecount *string `yaml:"feature_count,omitempty"` + featurecount *string `yaml:"featureCount,omitempty"` exceptions *string `yaml:"exceptions,omitempty"` } diff --git a/pkg/wms130/getmap_request.go b/pkg/wms130/getmap_request.go index ba1b373..a8326a9 100644 --- a/pkg/wms130/getmap_request.go +++ b/pkg/wms130/getmap_request.go @@ -35,9 +35,9 @@ const ( type GetMapRequest struct { XMLName xml.Name `xml:"GetMap" yaml:"getmap"` BaseRequest - StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledlayerdescriptor"` + StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledLayerDescriptor"` CRS CRS `xml:"CRS" yaml:"crs"` - BoundingBox BoundingBox `xml:"BoundingBox" yaml:"boundingbox"` + BoundingBox BoundingBox `xml:"BoundingBox" yaml:"boundingBox"` Output Output `xml:"Output" yaml:"output"` Exceptions *string `xml:"Exceptions" yaml:"exceptions"` // TODO: something with Time & Elevation @@ -192,7 +192,7 @@ type Size struct { // StyledLayerDescriptor struct type StyledLayerDescriptor struct { Version string `xml:"version,attr" yaml:"version"` - NamedLayer []NamedLayer `xml:"NamedLayer" yaml:"namedlayer"` + NamedLayer []NamedLayer `xml:"NamedLayer" yaml:"namedLayer"` } // Validate the StyledLayerDescriptor @@ -277,7 +277,7 @@ func (sld *StyledLayerDescriptor) getNamedStyles() []string { // NamedLayer struct type NamedLayer struct { Name string `xml:"Name" yaml:"name"` - NamedStyle *NamedStyle `xml:"NamedStyle" yaml:"namedstyle"` + NamedStyle *NamedStyle `xml:"NamedStyle" yaml:"namedStyle"` } // NamedStyle contains the style name that needs be applied diff --git a/pkg/wms130/getmap_test.go b/pkg/wms130/getmap_test.go index b2d861e..a7e290e 100644 --- a/pkg/wms130/getmap_test.go +++ b/pkg/wms130/getmap_test.go @@ -712,7 +712,7 @@ func TestGetMapValidate(t *testing.T) { }, }, }, - OptionalConstraints: OptionalConstraints{LayerLimit: 1, MaxWidth: 2048, MaxHeight: 2048}, + OptionalConstraints: &OptionalConstraints{LayerLimit: 1, MaxWidth: 2048, MaxHeight: 2048}, } var tests = []struct { diff --git a/pkg/wmts100/capabilities.go b/pkg/wmts100/capabilities.go index 8ceea3e..f937175 100644 --- a/pkg/wmts100/capabilities.go +++ b/pkg/wmts100/capabilities.go @@ -17,7 +17,7 @@ func (c *Contents) ParseYAML(doc []byte) error { // Contents struct for the WMTS 1.0.0 type Contents struct { Layer []Layer `xml:"Layer" yaml:"layer"` - TileMatrixSet []TileMatrixSet `xml:"TileMatrixSet" yaml:"tilematrixset"` + TileMatrixSet []TileMatrixSet `xml:"TileMatrixSet" yaml:"tileMatrixSet"` } // GetTilematrixsets helper function for collecting the provided TileMatrixSets, so th base can be cleanup for unused TileMatrixSets @@ -35,19 +35,19 @@ func (c Contents) GetTilematrixsets() map[string]bool { type Layer struct { Title string `xml:"ows:Title" yaml:"title"` Abstract string `xml:"ows:Abstract" yaml:"abstract"` - WGS84BoundingBox wsc110.WGS84BoundingBox `xml:"ows:WGS84BoundingBox" yaml:"wgs84boundingbox"` + WGS84BoundingBox wsc110.WGS84BoundingBox `xml:"ows:WGS84BoundingBox" yaml:"wgs84BoundingBox"` Identifier string `xml:"ows:Identifier" yaml:"identifier"` Metadata *Metadata `xml:"ows:Metadata,omitempty" yaml:"metadata"` Style []Style `xml:"Style" yaml:"style"` Format []string `xml:"Format" yaml:"format"` - InfoFormat []string `xml:"InfoFormat" yaml:"infoformat"` - TileMatrixSetLink []TileMatrixSetLink `xml:"TileMatrixSetLink" yaml:"tilematrixsetlink"` - ResourceURL []ResourceURL `xml:"ResourceURL" yaml:"resourceurl"` + InfoFormat []string `xml:"InfoFormat" yaml:"infoFormat"` + TileMatrixSetLink []TileMatrixSetLink `xml:"TileMatrixSetLink" yaml:"tileMatrixSetLink"` + ResourceURL []ResourceURL `xml:"ResourceURL" yaml:"resourceUrl"` } type ResourceURL struct { Format string `xml:"format,attr" yaml:"format"` - ResourceType string `xml:"resourceType,attr" yaml:"resourcetype"` + ResourceType string `xml:"resourceType,attr" yaml:"resourceType"` Template string `xml:"template,attr" yaml:"template"` } @@ -62,31 +62,31 @@ type Style struct { Abstract *string `xml:"ows:Abstract,omitempty" yaml:"abstract"` Keywords *wsc110.Keywords `xml:"Keywords,omitempty" yaml:"keywords"` Identifier string `xml:"ows:Identifier" yaml:"identifier"` - LegendURL []*LegendURL `xml:"LegendURL,omitempty" yaml:"legendurl"` - IsDefault *bool `xml:"isDefault,attr,omitempty" yaml:"isdefault"` + LegendURL []*LegendURL `xml:"LegendURL,omitempty" yaml:"legendUrl"` + IsDefault *bool `xml:"isDefault,attr,omitempty" yaml:"isDefault"` } // TileMatrixSetLink in struct for repeatability type TileMatrixSetLink struct { - TileMatrixSet string `xml:"TileMatrixSet" yaml:"tilematrixset"` + TileMatrixSet string `xml:"TileMatrixSet" yaml:"tileMatrixSet"` } // TileMatrixSet in struct for repeatability type TileMatrixSet struct { Identifier string `xml:"ows:Identifier" yaml:"identifier"` - SupportedCRS string `xml:"ows:SupportedCRS" yaml:"supportedcrs"` - TileMatrix []TileMatrix `xml:"TileMatrix" yaml:"tilematrix"` + SupportedCRS string `xml:"ows:SupportedCRS" yaml:"supportedCrs"` + TileMatrix []TileMatrix `xml:"TileMatrix" yaml:"tileMatrix"` } // TileMatrix in struct for repeatability type TileMatrix struct { Identifier string `xml:"ows:Identifier" yaml:"identifier"` - ScaleDenominator string `xml:"ScaleDenominator" yaml:"scaledenominator"` - TopLeftCorner string `xml:"TopLeftCorner" yaml:"topleftcorner"` - TileWidth string `xml:"TileWidth" yaml:"tilewidth"` - TileHeight string `xml:"TileHeight" yaml:"tileheight"` - MatrixWidth string `xml:"MatrixWidth" yaml:"matrixwidth"` - MatrixHeight string `xml:"MatrixHeight" yaml:"matrixheight"` + ScaleDenominator string `xml:"ScaleDenominator" yaml:"scaleDenominator"` + TopLeftCorner string `xml:"TopLeftCorner" yaml:"topLeftCorner"` + TileWidth string `xml:"TileWidth" yaml:"tileWidth"` + TileHeight string `xml:"TileHeight" yaml:"tileHeight"` + MatrixWidth string `xml:"MatrixWidth" yaml:"matrixWidth"` + MatrixHeight string `xml:"MatrixHeight" yaml:"matrixHeight"` } // LegendURL in struct for optionality diff --git a/pkg/wmts100/exception.go b/pkg/wmts100/exception.go index a2b41fc..2f78151 100644 --- a/pkg/wmts100/exception.go +++ b/pkg/wmts100/exception.go @@ -2,15 +2,14 @@ package wmts100 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" "github.com/pdok/ogc-specifications/pkg/wsc110" ) type exception struct { - XMLName xml.Name `xml:"ows:Exception"` - ExceptionText string `xml:",chardata" yaml:"exception"` - ExceptionCode string `xml:"exceptionCode,attr" yaml:"exceptioncode"` - LocatorCode string `xml:"locator,attr,omitempty" yaml:"locationcode"` + XMLName xml.Name `xml:"ows:Exception"` + common.ExceptionDetails } // ToExceptions promotes a single exception to an array of one diff --git a/pkg/wmts100/exception_codes.go b/pkg/wmts100/exception_codes.go index 2bd695a..1d9b309 100644 --- a/pkg/wmts100/exception_codes.go +++ b/pkg/wmts100/exception_codes.go @@ -1,12 +1,15 @@ package wmts100 -import "github.com/pdok/ogc-specifications/pkg/wsc110" +import ( + "github.com/pdok/ogc-specifications/pkg/common" + "github.com/pdok/ogc-specifications/pkg/wsc110" +) // TileOutOfRange exception func TileOutOfRange() wsc110.Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: "TileOutOfRange", ExceptionText: "TileRow or TileCol out of rangeName", LocatorCode: "", // TODO parse the right parameter TileRow or TileCol - } + }} } diff --git a/pkg/wmts100/getcapabilities_request.go b/pkg/wmts100/getcapabilities_request.go index 74c9a51..0ef9296 100644 --- a/pkg/wmts100/getcapabilities_request.go +++ b/pkg/wmts100/getcapabilities_request.go @@ -19,10 +19,10 @@ const ( // GetCapabilitiesRequest struct with the needed parameters/attributes needed for making a GetCapabilities request type GetCapabilitiesRequest struct { - XMLName xml.Name `xml:"GetCapabilities" yaml:"getcapabilities"` + XMLName xml.Name `xml:"GetCapabilities" yaml:"getCapabilities"` Service string `xml:"service,attr" yaml:"service"` Version string `xml:"version,attr" yaml:"version"` - Attr utils.XMLAttribute `xml:",attr"` + Attr utils.XMLAttribute `xml:",attr" yaml:"attr"` } // ParseXML builds a GetCapabilities object based on a XML document diff --git a/pkg/wmts100/getcapabilities_response.go b/pkg/wmts100/getcapabilities_response.go index 18d51a6..3e6e4cd 100644 --- a/pkg/wmts100/getcapabilities_response.go +++ b/pkg/wmts100/getcapabilities_response.go @@ -36,13 +36,13 @@ func (gc GetCapabilitiesResponse) ToXML() []byte { // GetCapabilitiesResponse base struct type GetCapabilitiesResponse struct { - XMLName xml.Name `xml:"Capabilities"` + XMLName xml.Name `xml:"Capabilities" yaml:"capabilities"` Namespaces `yaml:"namespaces"` - ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceidentification"` - ServiceProvider *wsc110.ServiceProvider `xml:"ows:ServiceProvider,omitempty" yaml:"serviceprovider"` - OperationsMetadata *OperationsMetadata `xml:"ows:OperationsMetadata,omitempty" yaml:"operationsmetadata"` + ServiceIdentification ServiceIdentification `xml:"ows:ServiceIdentification" yaml:"serviceIdentification"` + ServiceProvider *wsc110.ServiceProvider `xml:"ows:ServiceProvider,omitempty" yaml:"serviceProvider"` + OperationsMetadata *OperationsMetadata `xml:"ows:OperationsMetadata,omitempty" yaml:"operationsMetadata"` Contents Contents `xml:"Contents" yaml:"contents"` - ServiceMetadataURL *ServiceMetadataURL `xml:"ServiceMetadataURL,omitempty" yaml:"servicemetadataurl"` + ServiceMetadataURL *ServiceMetadataURL `xml:"ServiceMetadataURL,omitempty" yaml:"serviceMetadataUrl"` } // Namespaces struct containing the namespaces needed for the XML document @@ -53,17 +53,17 @@ type Namespaces struct { XmlnsXSI string `xml:"xmlns:xsi,attr" yaml:"xsi"` //http://www.w3.org/2001/XMLSchema-instance XmlnsGml string `xml:"xmlns:gml,attr" yaml:"gml"` //http://www.opengis.net/gml Version string `xml:"version,attr" yaml:"version"` - SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemalocation"` + SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemaLocation"` } type OperationsMetadata struct { - XMLName xml.Name `xml:"ows:OperationsMetadata"` - Operation []Operation `xml:"ows:Operation"` + XMLName xml.Name `xml:"ows:OperationsMetadata" yaml:"operationsMetadata"` + Operation []Operation `xml:"ows:Operation" yaml:"operation"` } // Operation struct for the WFS 2.0.0 type Operation struct { - Name string `xml:"name,attr"` + Name string `xml:"name,attr" yaml:"name"` DCP struct { HTTP struct { Get *Method `xml:"ows:Get,omitempty" yaml:"get,omitempty"` @@ -71,15 +71,15 @@ type Operation struct { } `xml:"ows:HTTP" yaml:"http"` } `xml:"ows:DCP" yaml:"dcp"` Parameter []struct { - Name string `xml:"name,attr"` + Name string `xml:"name,attr" yaml:"name"` AllowedValues struct { - Value []string `xml:"ows:Value"` - } `xml:"ows:AllowedValues"` - } `xml:"ows:Parameter"` + Value []string `xml:"ows:Value" yaml:"value"` + } `xml:"ows:AllowedValues" yaml:"allowedValues"` + } `xml:"ows:Parameter" yaml:"parameter"` Constraints []struct { Name string `xml:"name,attr" yaml:"name"` - NoValues string `xml:"ows:NoValues" yaml:"novalues"` - DefaultValue string `xml:"ows:DefaultValue" yaml:"defaultvalue"` + NoValues string `xml:"ows:NoValues" yaml:"noValues"` + DefaultValue string `xml:"ows:DefaultValue" yaml:"defaultValue"` } `xml:"ows:Constraint" yaml:"constraint"` } @@ -91,7 +91,7 @@ type Method struct { Name string `xml:"name,attr" yaml:"name"` AllowedValues struct { Value []string `xml:"ows:Value" yaml:"value"` - } `xml:"ows:AllowedValues" yaml:"allowedvalues"` + } `xml:"ows:AllowedValues" yaml:"allowedValues"` } `xml:"ows:Constraint" yaml:"constraint"` } @@ -100,10 +100,10 @@ type ServiceIdentification struct { Title string `xml:"ows:Title" yaml:"title"` Abstract string `xml:"ows:Abstract" yaml:"abstract"` Keywords *wsc110.Keywords `xml:"ows:Keywords,omitempty" yaml:"keywords"` - ServiceType string `xml:"ows:ServiceType" yaml:"servicetype"` - ServiceTypeVersion string `xml:"ows:ServiceTypeVersion" yaml:"servicetypeversion"` + ServiceType string `xml:"ows:ServiceType" yaml:"serviceType"` + ServiceTypeVersion string `xml:"ows:ServiceTypeVersion" yaml:"serviceTypeVersion"` Fees string `xml:"ows:Fees" yaml:"fees"` - AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessconstraints"` + AccessConstraints string `xml:"ows:AccessConstraints" yaml:"accessConstraints"` } // ServiceMetadataURL in struct for repeatability diff --git a/pkg/wsc110/boundingbox.go b/pkg/wsc110/boundingbox.go index 801da06..1023d4f 100644 --- a/pkg/wsc110/boundingbox.go +++ b/pkg/wsc110/boundingbox.go @@ -13,16 +13,16 @@ import ( type BoundingBoxUnmarshal struct { Crs string `xml:"crs,attr,omitempty" yaml:"crs,omitempty"` Dimensions string `xml:"dimensions,attr,omitempty" yaml:"dimensions,omitempty"` - LowerCorner Position `xml:"LowerCorner" yaml:"lowercorner"` - UpperCorner Position `xml:"UpperCorner" yaml:"uppercorner"` + LowerCorner Position `xml:"LowerCorner" yaml:"lowerCorner"` + UpperCorner Position `xml:"UpperCorner" yaml:"upperCorner"` } // BoundingBox struct type BoundingBox struct { Crs string `xml:"crs,attr,omitempty" yaml:"crs,omitempty"` Dimensions string `xml:"dimensions,attr,omitempty" yaml:"dimensions,omitempty"` - LowerCorner Position `xml:"ows:LowerCorner" yaml:"lowercorner"` - UpperCorner Position `xml:"ows:UpperCorner" yaml:"uppercorner"` + LowerCorner Position `xml:"ows:LowerCorner" yaml:"lowerCorner"` + UpperCorner Position `xml:"ows:UpperCorner" yaml:"upperCorner"` } // WGS84BoundingBox layers on the wsc110.BoundingBox @@ -38,7 +38,7 @@ func (b *BoundingBox) ToQueryParameters() string { return fmt.Sprintf("%f,%f,%f,%f", b.LowerCorner[0], b.LowerCorner[1], b.UpperCorner[0], b.UpperCorner[1]) } -//ParseString builds a BoundingBox based on a string +// ParseString builds a BoundingBox based on a string func (b *BoundingBox) ParseString(boundingbox string) Exception { result := strings.Split(boundingbox, ",") var lx, ly, ux, uy float64 diff --git a/pkg/wsc110/boundingbox_yaml.go b/pkg/wsc110/boundingbox_yaml.go index 788ea99..e554252 100644 --- a/pkg/wsc110/boundingbox_yaml.go +++ b/pkg/wsc110/boundingbox_yaml.go @@ -1,5 +1,10 @@ package wsc110 +import ( + "fmt" + "strconv" +) + // UnmarshalYAML Position func (p *Position) UnmarshalYAML(unmarshal func(interface{}) error) error { var s string @@ -12,3 +17,8 @@ func (p *Position) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } + +// MarshalYAML Position +func (p Position) MarshalYAML() (interface{}, error) { + return fmt.Sprintf("%s %s", strconv.FormatFloat(p[0], 'f', -1, 64), strconv.FormatFloat(p[1], 'f', -1, 64)), nil +} diff --git a/pkg/wsc110/boundingbox_yaml_test.go b/pkg/wsc110/boundingbox_yaml_test.go index 830b141..7d02f2a 100644 --- a/pkg/wsc110/boundingbox_yaml_test.go +++ b/pkg/wsc110/boundingbox_yaml_test.go @@ -29,3 +29,24 @@ func TestUnmarshalYAMLPosition(t *testing.T) { } } } + +func TestMarshalYAMLPosition(t *testing.T) { + var tests = []struct { + positionstring []byte + position Position + }{ + 0: {positionstring: []byte("2.52712538742158 50.2128625669452\n"), position: Position{2.52712538742158, 50.2128625669452}}, + 1: {positionstring: []byte("7.37402550506231 55.7211602557705\n"), position: Position{7.37402550506231, 55.7211602557705}}, + } + + for k, test := range tests { + pos, err := yaml.Marshal(test.position) + if err != nil { + t.Errorf("test: %d, yaml.Marshal failed with '%s'\n", k, err) + } else { + if string(pos) != string(test.positionstring) { + t.Errorf("test: %d, expected: %s,\n got: %s", k, test.positionstring, pos) + } + } + } +} diff --git a/pkg/wsc110/crs.go b/pkg/wsc110/crs.go index a695d01..b5781f0 100644 --- a/pkg/wsc110/crs.go +++ b/pkg/wsc110/crs.go @@ -6,7 +6,6 @@ import ( "strings" ) -// const ( codeSpace = `urn:ogc:def:crs:EPSG::` EPSG = `EPSG` diff --git a/pkg/wsc110/crs_yaml.go b/pkg/wsc110/crs_yaml.go index d30eb61..3f5e994 100644 --- a/pkg/wsc110/crs_yaml.go +++ b/pkg/wsc110/crs_yaml.go @@ -14,3 +14,7 @@ func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } + +func (c CRS) MarshalYAML() (interface{}, error) { + return c.String(), nil +} diff --git a/pkg/wsc110/exception.go b/pkg/wsc110/exception.go index f571d06..ae10460 100644 --- a/pkg/wsc110/exception.go +++ b/pkg/wsc110/exception.go @@ -2,6 +2,7 @@ package wsc110 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" ) // Exception interface @@ -14,21 +15,19 @@ type Exception interface { // exception type exception struct { - XMLName xml.Name `xml:"ows:Exception"` - ExceptionText string `xml:",chardata" yaml:"exception"` - ExceptionCode string `xml:"exceptionCode,attr" yaml:"exceptioncode"` - LocatorCode string `xml:"locator,attr,omitempty" yaml:"locationcode"` + XMLName xml.Name `xml:"ows:Exception"` + common.ExceptionDetails } // ExceptionReport struct type ExceptionReport struct { - XMLName xml.Name `xml:"ows:ExceptionReport" yaml:"exceptionreport"` - Ows string `xml:"xmlns:ows,attr,omitempty"` - Xsi string `xml:"xmlns:xsi,attr,omitempty"` - SchemaLocation string `xml:"xsi:schemaLocation,attr,omitempty"` + XMLName xml.Name `xml:"ows:ExceptionReport" yaml:"exceptionReport"` + Ows string `xml:"xmlns:ows,attr,omitempty" yaml:"ows"` + Xsi string `xml:"xmlns:xsi,attr,omitempty" yaml:"xsi"` + SchemaLocation string `xml:"xsi:schemaLocation,attr,omitempty" yaml:"schemaLocation"` Version string `xml:"version,attr" yaml:"version"` Language string `xml:"xml:lang,attr,omitempty" yaml:"lang,omitempty"` - Exception Exceptions `xml:"ows:Exception"` + Exception Exceptions `xml:"ows:Exception" yaml:"exception"` } // Exceptions is a array of the Exception interface diff --git a/pkg/wsc110/exception_codes.go b/pkg/wsc110/exception_codes.go index 713fbe3..cdf49af 100644 --- a/pkg/wsc110/exception_codes.go +++ b/pkg/wsc110/exception_codes.go @@ -2,71 +2,74 @@ package wsc110 import ( "fmt" + "github.com/pdok/ogc-specifications/pkg/common" ) // OperationNotSupported exception func OperationNotSupported(message string) Exception { return exception{ - ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), - ExceptionCode: `OperationNotSupported`, - LocatorCode: message, + ExceptionDetails: common.ExceptionDetails{ + ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), + ExceptionCode: `OperationNotSupported`, + LocatorCode: message, + }, } } // MissingParameterValue exception func MissingParameterValue(s ...string) Exception { if len(s) >= 2 { - return exception{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } - return exception{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} } // InvalidParameterValue exception func InvalidParameterValue(value, locator string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s contains a invalid value: %s", locator, value), LocatorCode: value, ExceptionCode: `InvalidParameterValue`, - } + }} } // VersionNegotiationFailed exception func VersionNegotiationFailed(version string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s is an invalid version number", version), ExceptionCode: `VersionNegotiationFailed`, LocatorCode: "VERSION", - } + }} } // InvalidUpdateSequence exception func InvalidUpdateSequence() Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidUpdateSequence`, - } + }} } // OptionNotSupported exception func OptionNotSupported(s ...string) Exception { if len(s) == 1 { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: s[0], ExceptionCode: `OptionNotSupported`, - } + }} } - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `OptionNotSupported`, - } + }} } // NoApplicableCode exception func NoApplicableCode(message string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: message, ExceptionCode: `NoApplicableCode`, - } + }} } diff --git a/pkg/wsc110/exception_test.go b/pkg/wsc110/exception_test.go index dfc48ef..44c9702 100644 --- a/pkg/wsc110/exception_test.go +++ b/pkg/wsc110/exception_test.go @@ -1,6 +1,7 @@ package wsc110 import ( + "github.com/pdok/ogc-specifications/pkg/common" "testing" ) @@ -11,7 +12,7 @@ func TestOWSException(t *testing.T) { exceptionCode string locatorCode string }{ - 0: {exception: exception{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}, + 0: {exception: exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, exceptionText: "", exceptionCode: "", locatorCode: "", diff --git a/pkg/wsc110/keywords.go b/pkg/wsc110/keywords.go index 7eeb266..3d0be65 100644 --- a/pkg/wsc110/keywords.go +++ b/pkg/wsc110/keywords.go @@ -2,9 +2,9 @@ package wsc110 // Keywords in struct for repeatability type Keywords struct { - Keyword []string `xml:"ows:Keyword"` + Keyword []string `xml:"ows:Keyword" yaml:"keyword"` Type *struct { - Text string `xml:",chardata"` - CodeSpace *string `xml:"codeSpace,attr,omitempty"` - } `xml:"ows:Type"` + Text string `xml:",chardata" yaml:"text"` + CodeSpace *string `xml:"codeSpace,attr,omitempty" yaml:"codeSpace"` + } `xml:"ows:Type" yaml:"type,omitempty"` } diff --git a/pkg/wsc110/service_provider.go b/pkg/wsc110/service_provider.go index dfbcc7b..7603a8d 100644 --- a/pkg/wsc110/service_provider.go +++ b/pkg/wsc110/service_provider.go @@ -1,34 +1,34 @@ package wsc110 type ServiceProvider struct { - ProviderName string `xml:"ows:ProviderName" yaml:"providername"` + ProviderName string `xml:"ows:ProviderName" yaml:"providerName"` ProviderSite struct { Type string `xml:"xlink:type,attr" yaml:"type"` Href string `xml:"xlink:href,attr" yaml:"href"` - } `xml:"ows:ProviderSite" yaml:"providersite"` + } `xml:"ows:ProviderSite" yaml:"providerSite"` ServiceContact struct { - IndividualName string `xml:"ows:IndividualName,omitempty" yaml:"individualname"` - PositionName string `xml:"ows:PositionName,omitempty" yaml:"positionname"` + IndividualName string `xml:"ows:IndividualName,omitempty" yaml:"individualName"` + PositionName string `xml:"ows:PositionName,omitempty" yaml:"positionName"` ContactInfo struct { Phone struct { Voice string `xml:"ows:Voice" yaml:"voice"` Facsimile string `xml:"ows:Facsimile" yaml:"facsimile"` } `xml:"ows:Phone" yaml:"phone"` Address struct { - DeliveryPoint string `xml:"ows:DeliveryPoint" yaml:"deliverypoint"` + DeliveryPoint string `xml:"ows:DeliveryPoint" yaml:"deliveryPoint"` City string `xml:"ows:City" yaml:"city"` - AdministrativeArea string `xml:"ows:AdministrativeArea" yaml:"administrativearea"` - PostalCode string `xml:"ows:PostalCode" yaml:"postalcode"` + AdministrativeArea string `xml:"ows:AdministrativeArea" yaml:"administrativeArea"` + PostalCode string `xml:"ows:PostalCode" yaml:"postalCode"` Country string `xml:"ows:Country" yaml:"country"` - ElectronicMailAddress string `xml:"ows:ElectronicMailAddress" yaml:"electronicmailaddress"` + ElectronicMailAddress string `xml:"ows:ElectronicMailAddress" yaml:"electronicMailAddress"` } `xml:"ows:Address" yaml:"address"` OnlineResource *struct { Type string `xml:"xlink:type,attr,omitempty" yaml:"type"` Href string `xml:"xlink:href,attr,omitempty" yaml:"href"` - } `xml:"ows:OnlineResource,omitempty" yaml:"onlineresource"` - HoursOfService string `xml:"ows:HoursOfService,omitempty" yaml:"hoursofservice"` - ContactInstructions string `xml:"ows:ContactInstructions,omitempty" yaml:"contactinstructions"` - } `xml:"ows:ContactInfo" yaml:"contactinfo"` + } `xml:"ows:OnlineResource,omitempty" yaml:"onlineResource"` + HoursOfService string `xml:"ows:HoursOfService,omitempty" yaml:"hoursOfService"` + ContactInstructions string `xml:"ows:ContactInstructions,omitempty" yaml:"contactInstructions"` + } `xml:"ows:ContactInfo" yaml:"contactInfo"` Role string `xml:"ows:Role,omitempty" yaml:"role"` - } `xml:"ows:ServiceContact" yaml:"servicecontact"` + } `xml:"ows:ServiceContact" yaml:"serviceContact"` } diff --git a/pkg/wsc200/exception.go b/pkg/wsc200/exception.go index 7dbca81..f15b0a4 100644 --- a/pkg/wsc200/exception.go +++ b/pkg/wsc200/exception.go @@ -2,6 +2,7 @@ package wsc200 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" ) // Exception interface @@ -14,21 +15,19 @@ type Exception interface { // exception type exception struct { - XMLName xml.Name `xml:"ows:Exception"` - ExceptionText string `xml:",chardata" yaml:"exception"` - ExceptionCode string `xml:"exceptionCode,attr" yaml:"exceptioncode"` - LocatorCode string `xml:"locator,attr,omitempty" yaml:"locationcode"` + XMLName xml.Name `xml:"ows:Exception"` + common.ExceptionDetails } // ExceptionReport struct type ExceptionReport struct { - XMLName xml.Name `xml:"ows:ExceptionReport" yaml:"exceptionreport"` - Ows string `xml:"xmlns:ows,attr,omitempty"` - Xsi string `xml:"xmlns:xsi,attr,omitempty"` - SchemaLocation string `xml:"xsi:schemaLocation,attr,omitempty"` - Version string `xml:"version,attr" yaml:"version"` + XMLName xml.Name `xml:"ows:ExceptionReport" yaml:"exceptionReport"` + Ows string `xml:"xmlns:ows,attr,omitempty" yaml:"ows"` + Xsi string `xml:"xmlns:xsi,attr,omitempty" yaml:"xsi"` + SchemaLocation string `xml:"xsi:schemaLocation,attr,omitempty" yaml:"schemaLocation"` + Version string `xml:"version,attr" yaml:"version" yaml:"version"` Language string `xml:"xml:lang,attr,omitempty" yaml:"lang,omitempty"` - Exception Exceptions `xml:"ows:Exception"` + Exception Exceptions `xml:"ows:Exception" yaml:"exception"` } // Exceptions is a array of the Exception interface diff --git a/pkg/wsc200/exception_codes.go b/pkg/wsc200/exception_codes.go index e4d65c5..ea53398 100644 --- a/pkg/wsc200/exception_codes.go +++ b/pkg/wsc200/exception_codes.go @@ -2,58 +2,59 @@ package wsc200 import ( "fmt" + "github.com/pdok/ogc-specifications/pkg/common" ) // OperationNotSupported exception func OperationNotSupported(message string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), ExceptionCode: `OperationNotSupported`, LocatorCode: message, - } + }} } // MissingParameterValue exception func MissingParameterValue(s ...string) Exception { if len(s) >= 2 { - return exception{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } - return exception{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} } // InvalidParameterValue exception func InvalidParameterValue(value, locator string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s contains a invalid value: %s", locator, value), LocatorCode: value, ExceptionCode: `InvalidParameterValue`, - } + }} } // VersionNegotiationFailed exception func VersionNegotiationFailed(version string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s is an invalid version number", version), ExceptionCode: `VersionNegotiationFailed`, LocatorCode: "VERSION", - } + }} } // InvalidUpdateSequence exception func InvalidUpdateSequence() Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidUpdateSequence`, - } + }} } // NoApplicableCode exception func NoApplicableCode(message string) Exception { - return exception{ + return exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: message, ExceptionCode: `NoApplicableCode`, - } + }} } diff --git a/pkg/wsc200/exception_test.go b/pkg/wsc200/exception_test.go index 289fb46..c5f1c8b 100644 --- a/pkg/wsc200/exception_test.go +++ b/pkg/wsc200/exception_test.go @@ -1,6 +1,7 @@ package wsc200 import ( + "github.com/pdok/ogc-specifications/pkg/common" "testing" ) @@ -11,7 +12,7 @@ func TestOWSException(t *testing.T) { exceptionCode string locatorCode string }{ - 0: {exception: exception{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}, + 0: {exception: exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, exceptionText: "", exceptionCode: "", locatorCode: "",