initial
This commit is contained in:
176
mapping.go
Normal file
176
mapping.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package gliffy2drawio
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const DefaultTranslationPath = "java/gliffy/importer/gliffyTranslation.properties"
|
||||
|
||||
type StencilTranslator struct {
|
||||
once sync.Once
|
||||
path string
|
||||
translations map[string]string
|
||||
customFile string
|
||||
}
|
||||
|
||||
func NewStencilTranslator(path string) *StencilTranslator {
|
||||
return &StencilTranslator{path: path}
|
||||
}
|
||||
|
||||
// WithCustomMapping allows specifying an optional JSON file (map[string]string) for extra translations.
|
||||
func (s *StencilTranslator) WithCustomMapping(jsonPath string) *StencilTranslator {
|
||||
s.customFile = jsonPath
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *StencilTranslator) Translate(uid, tid string) string {
|
||||
s.once.Do(s.load)
|
||||
if s.translations == nil {
|
||||
return ""
|
||||
}
|
||||
if v, ok := s.translations[uid]; ok {
|
||||
return v
|
||||
}
|
||||
if tid != "" {
|
||||
if v, ok := s.translations[tid]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *StencilTranslator) load() {
|
||||
path := s.path
|
||||
if path == "" {
|
||||
path = DefaultTranslationPath
|
||||
}
|
||||
file, err := os.Open(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
s.translations = make(map[string]string)
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
s.translations[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
// Hard-coded additions for shapes absent from properties.
|
||||
for k, v := range map[string]string{
|
||||
"gshape.aws_v3.database.Amazon_RDS_PostgreSQL_instance_light_bg": "mxgraph.aws4.rds_postgresql_instance;fillColor=#3334B9",
|
||||
"gstencil.aws_v3.database.Amazon_RDS_PostgreSQL_instance_light_bg": "mxgraph.aws4.rds_postgresql_instance;fillColor=#3334B9",
|
||||
} {
|
||||
if _, ok := s.translations[k]; !ok {
|
||||
s.translations[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Load optional custom JSON mapping file if provided.
|
||||
if s.customFile != "" {
|
||||
if data, err := os.ReadFile(filepath.Clean(s.customFile)); err == nil {
|
||||
var extra map[string]string
|
||||
if err := json.Unmarshal(data, &extra); err == nil {
|
||||
for k, v := range extra {
|
||||
if _, exists := s.translations[k]; !exists {
|
||||
s.translations[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DashStyleMapping(value string, width int) string {
|
||||
if value == "" {
|
||||
return ""
|
||||
}
|
||||
parts := strings.Split(value, ",")
|
||||
for i, p := range parts {
|
||||
if f, err := strconv.ParseFloat(strings.TrimSpace(p), 64); err == nil {
|
||||
parts[i] = floatToString(f * float64(width))
|
||||
}
|
||||
}
|
||||
return "dashed=1;fixDash=1;dashPattern=" + strings.Join(parts, " ") + ";"
|
||||
}
|
||||
|
||||
var lineMapping = map[string]string{
|
||||
"linear": "",
|
||||
"orthogonal": "edgeStyle=orthogonal;",
|
||||
"quadratic": "curved=1;edgeStyle=orthogonalEdgeStyle;",
|
||||
}
|
||||
|
||||
func LineMapping(style string) string {
|
||||
return lineMapping[style]
|
||||
}
|
||||
|
||||
type ArrowStyle struct {
|
||||
Name string
|
||||
Fill bool
|
||||
Size int
|
||||
Spacing int
|
||||
}
|
||||
|
||||
func (a ArrowStyle) ToString(start bool) string {
|
||||
fill := 0
|
||||
if a.Fill {
|
||||
fill = 1
|
||||
}
|
||||
if start {
|
||||
return "startArrow=" + a.Name + ";startFill=" + strconv.Itoa(fill) + ";startSize=" + strconv.Itoa(a.Size) + optionalSpacing("sourcePerimeterSpacing", a.Spacing) + ";"
|
||||
}
|
||||
return "endArrow=" + a.Name + ";endFill=" + strconv.Itoa(fill) + ";endSize=" + strconv.Itoa(a.Size) + optionalSpacing("targetPerimeterSpacing", a.Spacing) + ";"
|
||||
}
|
||||
|
||||
func optionalSpacing(key string, v int) string {
|
||||
if v == 0 {
|
||||
return ""
|
||||
}
|
||||
return ";" + key + "=" + strconv.Itoa(v) + ";"
|
||||
}
|
||||
|
||||
var arrowMapping = map[int]ArrowStyle{
|
||||
0: {Name: "none", Fill: false, Size: 6},
|
||||
1: {Name: "open", Fill: false, Size: 6},
|
||||
2: {Name: "block", Fill: true, Size: 6},
|
||||
3: {Name: "block", Fill: false, Size: 6},
|
||||
4: {Name: "block", Fill: false, Size: 10},
|
||||
5: {Name: "diamond", Fill: false, Size: 12},
|
||||
6: {Name: "open", Fill: false, Size: 10},
|
||||
7: {Name: "diamond", Fill: true, Size: 12},
|
||||
8: {Name: "classic", Fill: true, Size: 6},
|
||||
9: {Name: "ERzeroToMany", Fill: true, Size: 10},
|
||||
10: {Name: "ERoneToMany", Fill: true, Size: 10},
|
||||
11: {Name: "ERmandOne", Fill: true, Size: 10},
|
||||
12: {Name: "ERone", Fill: true, Size: 10},
|
||||
13: {Name: "ERzeroToOne", Fill: true, Size: 10},
|
||||
14: {Name: "ERmany", Fill: true, Size: 10},
|
||||
15: {Name: "oval", Fill: false, Size: 10, Spacing: 6},
|
||||
16: {Name: "dash", Fill: false, Size: 6},
|
||||
17: {Name: "block", Fill: true, Size: 6},
|
||||
18: {Name: "classic", Fill: true, Size: 6},
|
||||
19: {Name: "openAsync", Fill: false, Size: 10},
|
||||
}
|
||||
|
||||
func ArrowMapping(id *int) ArrowStyle {
|
||||
if id == nil {
|
||||
return arrowMapping[0]
|
||||
}
|
||||
if a, ok := arrowMapping[*id]; ok {
|
||||
return a
|
||||
}
|
||||
return arrowMapping[0]
|
||||
}
|
||||
Reference in New Issue
Block a user