github.com/CyCoreSystems/ari@v4.8.4+incompatible/internal/eventgen/main.go (about)

     1  package main
     2  
     3  // Generate event code from the events.json swagger
     4  
     5  import (
     6  	"encoding/json"
     7  	"log"
     8  	"os"
     9  	"sort"
    10  	"strings"
    11  	"text/template"
    12  )
    13  
    14  var typeMappings map[string]string
    15  
    16  func init() {
    17  	typeMappings = make(map[string]string)
    18  	typeMappings["boolean"] = "bool"
    19  	typeMappings["Channel"] = "ChannelData"
    20  	typeMappings["List[string]"] = "[]string"
    21  	typeMappings["Bridge"] = "BridgeData"
    22  	typeMappings["Playback"] = "PlaybackData"
    23  	typeMappings["LiveRecording"] = "LiveRecordingData"
    24  	typeMappings["StoredRecording"] = "StoredRecordingData"
    25  	typeMappings["Endpoint"] = "EndpointData"
    26  	typeMappings["DeviceState"] = "DeviceStateData"
    27  	typeMappings["TextMessage"] = "TextMessageData"
    28  	typeMappings["object"] = "interface{}"
    29  }
    30  
    31  type event struct {
    32  	Name        string
    33  	Event       string
    34  	Description string
    35  	Properties  propList
    36  }
    37  
    38  type prop struct {
    39  	Name        string
    40  	JSONName    string
    41  	Mapping     string
    42  	Type        string
    43  	Description string
    44  	Required    bool
    45  }
    46  
    47  type propList []prop
    48  
    49  func (pl propList) Len() int {
    50  	return len(pl)
    51  }
    52  
    53  func (pl propList) Less(l int, r int) bool {
    54  	return pl[l].Name < pl[r].Name
    55  }
    56  
    57  func (pl propList) Swap(l int, r int) {
    58  	tmp := pl[r]
    59  	pl[r] = pl[l]
    60  	pl[l] = tmp
    61  }
    62  
    63  type eventList []event
    64  
    65  func (el eventList) Len() int {
    66  	return len(el)
    67  }
    68  
    69  func (el eventList) Less(l int, r int) bool {
    70  	return el[l].Name < el[r].Name
    71  }
    72  
    73  func (el eventList) Swap(l int, r int) {
    74  	tmp := el[r]
    75  	el[r] = el[l]
    76  	el[l] = tmp
    77  }
    78  
    79  func main() {
    80  	if len(os.Args) < 3 {
    81  		log.Fatalf("Usage: %s <template> <specFile.json>\n", os.Args[0])
    82  		return
    83  	}
    84  	templateFile := os.Args[1]
    85  	specFile := os.Args[2]
    86  
    87  	// load template
    88  	tmpl, err := template.New("eventsTemplate").ParseFiles(templateFile)
    89  	if err != nil {
    90  		log.Fatalln("failed to parse template", err)
    91  	}
    92  
    93  	// load file
    94  	input, err := os.Open(specFile)
    95  	if err != nil {
    96  		log.Fatalln("failed to open event definition file", err)
    97  	}
    98  	defer input.Close()
    99  
   100  	// parse data
   101  	data := make(map[string]interface{})
   102  	dec := json.NewDecoder(input)
   103  
   104  	if err := dec.Decode(&data); err != nil {
   105  		log.Fatalln("failed to decode event definition file", err)
   106  	}
   107  
   108  	// convert data
   109  
   110  	var events eventList
   111  
   112  	models, ok := data["models"].(map[string]interface{})
   113  	if !ok {
   114  		log.Fatalln("failed to get models")
   115  	}
   116  	if len(models) < 1 {
   117  		log.Fatalln("no models found")
   118  	}
   119  
   120  	for mkey, m := range models {
   121  		model := m.(map[string]interface{})
   122  		name := strings.Replace(mkey, "Id", "ID", -1)
   123  
   124  		if name == "Message" || name == "Event" {
   125  			continue
   126  		}
   127  
   128  		var pl propList
   129  		props := model["properties"].(map[string]interface{})
   130  		for pkey, p := range props {
   131  			propm := p.(map[string]interface{})
   132  			desc, _ := propm["description"].(string)
   133  
   134  			desc = strings.Replace(desc, "\n", "", -1)
   135  			desc = strings.Replace(desc, "\r", "", -1)
   136  
   137  			if desc != "" {
   138  				desc = "// " + desc
   139  			}
   140  
   141  			t, ok := typeMappings[propm["type"].(string)]
   142  			if !ok {
   143  				t = propm["type"].(string)
   144  			}
   145  
   146  			items := strings.Split(pkey, "_")
   147  			var name string
   148  			for _, x := range items {
   149  				name += strings.Title(x)
   150  			}
   151  
   152  			required := true
   153  			if req, ok := propm["required"].(bool); ok {
   154  				required = req
   155  			}
   156  
   157  			mapping := "`json:\"" + pkey + "\"` "
   158  			if !required {
   159  				mapping = "`json:\"" + pkey + ",omitempty\"`"
   160  			}
   161  
   162  			pl = append(pl, prop{
   163  				Name:        name,
   164  				Mapping:     mapping,
   165  				JSONName:    pkey,
   166  				Type:        t,
   167  				Description: desc,
   168  			})
   169  		}
   170  
   171  		sort.Sort(pl)
   172  
   173  		desc, _ := model["description"].(string)
   174  		desc = strings.Replace(desc, "\n", "", -1)
   175  		desc = strings.Replace(desc, "\r", "", -1)
   176  
   177  		events = append(events, event{
   178  			Name:        name,
   179  			Event:       mkey,
   180  			Description: desc,
   181  			Properties:  pl,
   182  		})
   183  	}
   184  
   185  	sort.Sort(events)
   186  
   187  	if err := tmpl.ExecuteTemplate(os.Stdout, "template.tmpl", events); err != nil {
   188  		log.Fatalln("failed to execute template:", err)
   189  	}
   190  }