-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathddex.go
More file actions
140 lines (118 loc) · 3.78 KB
/
ddex.go
File metadata and controls
140 lines (118 loc) · 3.78 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package ddex
import (
"encoding/xml"
"fmt"
"regexp"
"strings"
ernv383 "github.com/alecsavvy/ddex-go/gen/ddex/ern/v383"
ernv43 "github.com/alecsavvy/ddex-go/gen/ddex/ern/v43"
ernv432 "github.com/alecsavvy/ddex-go/gen/ddex/ern/v432"
meadv11 "github.com/alecsavvy/ddex-go/gen/ddex/mead/v11"
piev10 "github.com/alecsavvy/ddex-go/gen/ddex/pie/v10"
)
// Versioned type aliases for discoverability of pure XML types
type (
// ERN v4.3 - Main message types
NewReleaseMessageV43 = ernv43.NewReleaseMessage
PurgeReleaseMessageV43 = ernv43.PurgeReleaseMessage
// ERN v3.8.3 - Main message types
NewReleaseMessageV383 = ernv383.NewReleaseMessage
PurgeReleaseMessageV383 = ernv383.PurgeReleaseMessage
// ERN v4.3.2 - Main message types
NewReleaseMessageV432 = ernv432.NewReleaseMessage
PurgeReleaseMessageV432 = ernv432.PurgeReleaseMessage
// MEAD v1.1 types
MeadMessageV11 = meadv11.MeadMessage
// PIE v1.0 types
PieMessageV10 = piev10.PieMessage
PieRequestMessageV10 = piev10.PieRequestMessage
)
// ERNVersion represents a supported ERN version
type ERNVersion string
const (
ERNv43 ERNVersion = "43"
ERNv383 ERNVersion = "383"
ERNv432 ERNVersion = "432"
)
// ERNMessage represents any ERN message type
type ERNMessage interface {
// All ERN messages can be marshaled to XML
xml.Marshaler
}
// DetectERNVersion detects the ERN version from XML content
func DetectERNVersion(xmlData []byte) (ERNVersion, error) {
xmlStr := string(xmlData)
// Look for ERN namespace patterns
ernPattern := regexp.MustCompile(`xmlns(?::\w+)?="http://ddex\.net/xml/ern/v?(\d+(?:\.\d+)*)`)
matches := ernPattern.FindStringSubmatch(xmlStr)
if len(matches) < 2 {
return "", fmt.Errorf("could not detect ERN version from XML")
}
version := strings.ReplaceAll(matches[1], ".", "")
switch version {
case "43":
return ERNv43, nil
case "383":
return ERNv383, nil
case "432":
return ERNv432, nil
default:
return "", fmt.Errorf("unsupported ERN version: %s", version)
}
}
// ParseERN automatically detects version and parses ERN XML to appropriate message type
func ParseERN(xmlData []byte) (ERNMessage, ERNVersion, error) {
version, err := DetectERNVersion(xmlData)
if err != nil {
return nil, "", err
}
message, err := ParseERNWithVersion(xmlData, version)
return message, version, err
}
// ParseERNWithVersion parses ERN XML to specific version message type
func ParseERNWithVersion(xmlData []byte, version ERNVersion) (ERNMessage, error) {
xmlStr := string(xmlData)
// Determine message type (handle both namespaced and non-namespaced forms)
if strings.Contains(xmlStr, "NewReleaseMessage") {
return parseNewReleaseMessage(xmlData, version)
} else if strings.Contains(xmlStr, "PurgeReleaseMessage") {
return parsePurgeReleaseMessage(xmlData, version)
}
return nil, fmt.Errorf("unknown ERN message type")
}
func parseNewReleaseMessage(xmlData []byte, version ERNVersion) (ERNMessage, error) {
switch version {
case ERNv43:
var msg NewReleaseMessageV43
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
case ERNv383:
var msg NewReleaseMessageV383
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
case ERNv432:
var msg NewReleaseMessageV432
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
default:
return nil, fmt.Errorf("unsupported ERN version: %s", version)
}
}
func parsePurgeReleaseMessage(xmlData []byte, version ERNVersion) (ERNMessage, error) {
switch version {
case ERNv43:
var msg PurgeReleaseMessageV43
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
case ERNv383:
var msg PurgeReleaseMessageV383
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
case ERNv432:
var msg PurgeReleaseMessageV432
err := xml.Unmarshal(xmlData, &msg)
return &msg, err
default:
return nil, fmt.Errorf("unsupported ERN version: %s", version)
}
}