This repository has been archived by the owner on Aug 16, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
merger.go
119 lines (105 loc) · 2.65 KB
/
merger.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package merging
import (
"context"
"github.com/reearth/reearth-backend/pkg/layer"
"github.com/reearth/reearth-backend/pkg/property"
)
type Merger struct {
LayerLoader layer.Loader
PropertyLoader property.Loader
}
func (m *Merger) MergeLayer(ctx context.Context, l layer.Layer, parent *layer.Group) (MergedLayer, error) {
if m == nil || l == nil {
return nil, nil
}
common, err := m.mergeCommon(ctx, l, parent)
if err != nil {
return nil, err
}
if common == nil {
return nil, nil
}
if li := layer.ToLayerItem(l); li != nil {
// item
return &MergedLayerItem{*common}, nil
} else if lg := layer.ToLayerGroup(l); lg != nil {
// group
layers, err := m.LayerLoader(ctx, lg.Layers().Layers()...)
if err != nil {
return nil, err
}
children := make([]MergedLayer, 0, len(layers))
for _, c := range layers {
if c == nil {
continue
}
ml, err := m.MergeLayer(ctx, *c, lg)
if err != nil {
return nil, err
}
children = append(children, ml)
}
return &MergedLayerGroup{
MergedLayerCommon: *common,
Children: children,
}, nil
}
return nil, nil
}
func (m *Merger) MergeLayerFromID(ctx context.Context, i layer.ID, parent *layer.Group) (MergedLayer, error) {
l, err := m.LayerLoader(ctx, i)
if err != nil {
return nil, err
}
if len(l) == 0 || l[0] == nil {
return nil, nil
}
return m.MergeLayer(ctx, *l[0], parent)
}
func (m *Merger) mergeCommon(ctx context.Context, original layer.Layer, parent *layer.Group) (p *MergedLayerCommon, e error) {
ml := layer.Merge(original, parent)
if ml == nil {
return
}
properties, err := m.PropertyLoader(ctx, ml.Properties()...)
if err != nil {
e = err
return
}
var infobox *MergedInfobox
if ml.Infobox != nil {
fields := make([]*MergedInfoboxField, 0, len(ml.Infobox.Fields))
for _, f := range ml.Infobox.Fields {
fields = append(fields, &MergedInfoboxField{
MergedInfoboxField: *f,
Property: mergeProperty(f.Property, properties),
})
}
infobox = &MergedInfobox{
MergedInfobox: *ml.Infobox,
Fields: fields,
Property: mergeProperty(ml.Infobox.Property, properties),
}
}
p = &MergedLayerCommon{
Merged: *ml,
Property: mergeProperty(ml.Property, properties),
Infobox: infobox,
}
return
}
func mergeProperty(ml *property.MergedMetadata, properties []*property.Property) *property.Merged {
var op, pp *property.Property
for _, p := range properties {
if ml.Original != nil && p.ID() == *ml.Original {
op = p
}
if ml.Parent != nil && p.ID() == *ml.Parent {
pp = p
}
if (ml.Original == nil || op != nil) && (ml.Parent == nil || pp != nil) {
break
}
}
return ml.Merge(op, pp)
}