/
envelope_builder.go
101 lines (83 loc) · 2.48 KB
/
envelope_builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package soap
import (
"encoding/xml"
"net/http"
)
// EnvBuilder is a SOAP Envelope builder.
type EnvBuilder struct {
headers []interface{}
payload []interface{}
env Envelope
xmlns map[string]string
}
// SetHeaders sets the SOAP headers, overriding the previous ones.
func (bldr *EnvBuilder) SetHeaders(hdrs ...interface{}) *EnvBuilder {
bldr.headers = hdrs
return bldr
}
// SetPayload sets the payload, overriding the previous one.
func (bldr *EnvBuilder) SetPayload(items ...interface{}) *EnvBuilder {
bldr.payload = items
return bldr
}
// Env will return the latest envelope built with this builder.
// If neither Build nor BuildHTTPRequest has been called successfully,
// nil will be returned.
func (bldr *EnvBuilder) Env() Envelope {
return bldr.env
}
// Build builds an Envelope for the specified SOAP version.
func (bldr *EnvBuilder) Build(version string) (Envelope, error) {
if !isValidVersion(version) {
return nil, ErrInvalidVersion
}
bdy, err := xml.Marshal(bldr.payload)
if err != nil {
return nil, err
}
var env Envelope = &Envelope11{BodyElem: Body11{PayloadElem: bdy}, Xmlns: bldr.xmlns}
if version == V12 {
env = &Envelope12{BodyElem: Body12{PayloadElem: bdy}, Xmlns: bldr.xmlns}
}
if len(bldr.headers) > 0 {
hdr, err := xml.Marshal(bldr.headers)
if err != nil {
return nil, err
}
if len(hdr) > 0 {
env.setHeader(&Header{Content: hdr})
}
}
return env, nil
}
// BuildHTTPRequest builds a HTTP Request.
func (bldr *EnvBuilder) BuildHTTPRequest(version string, action string) (*http.Request, error) {
env, err := bldr.Build(version)
if err != nil {
return nil, err
}
return env.GetHTTPRequest(action)
}
// NewEnvBuilder returns a new Envelope builder.
func NewEnvBuilder() *EnvBuilder {
return &EnvBuilder{}
}
// EnvBuilderOption represents a configuration function for an EnvBuilder.
// An Option will configure or set up internal details of an EnvBuilder.
type EnvBuilderOption func(*EnvBuilder)
// SetXmlns returns a configuration function to configure the namespace prefix of an EnvBuilderOption.
func SetXmlns(xmlns map[string]string) EnvBuilderOption {
return func(bldr *EnvBuilder) {
bldr.xmlns = xmlns
}
}
// NewEnvelope returns a new Envelope based on the parameters passed.
func NewEnvelope(version string, header interface{}, payload interface{}, opts ...EnvBuilderOption) (Envelope, error) {
bldr := NewEnvBuilder().
SetHeaders(header).
SetPayload(payload)
for _, opt := range opts {
opt(bldr)
}
return bldr.Build(version)
}