|
|
@ -1,14 +1,14 @@ |
|
|
package jdr |
|
|
package jdr |
|
|
|
|
|
|
|
|
import( |
|
|
|
|
|
"html/template" |
|
|
|
|
|
|
|
|
|
|
|
"fmt" |
|
|
|
|
|
"log" |
|
|
|
|
|
"errors" |
|
|
|
|
|
"strings" |
|
|
|
|
|
"strconv" |
|
|
|
|
|
"regexp" |
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
|
"html/template" |
|
|
|
|
|
|
|
|
|
|
|
"errors" |
|
|
|
|
|
"fmt" |
|
|
|
|
|
"log" |
|
|
|
|
|
"regexp" |
|
|
|
|
|
"strconv" |
|
|
|
|
|
"strings" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
var regexp_d = regexp.MustCompile(`^[1-9][0-9]*d([468]|1[02]|20|100)$`) |
|
|
var regexp_d = regexp.MustCompile(`^[1-9][0-9]*d([468]|1[02]|20|100)$`) |
|
|
@ -16,443 +16,443 @@ var regexp_d = regexp.MustCompile(`^[1-9][0-9]*d([468]|1[02]|20|100)$`) |
|
|
type JsonValue interface{} |
|
|
type JsonValue interface{} |
|
|
|
|
|
|
|
|
type VariableType interface { |
|
|
type VariableType interface { |
|
|
Name() string |
|
|
|
|
|
Validate(value JsonValue) bool |
|
|
|
|
|
ToHTML(value JsonValue) (template.HTML, error) |
|
|
|
|
|
DefaultValue() JsonValue |
|
|
|
|
|
|
|
|
Name() string |
|
|
|
|
|
Validate(value JsonValue) bool |
|
|
|
|
|
ToHTML(value JsonValue) (template.HTML, error) |
|
|
|
|
|
DefaultValue() JsonValue |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func validateCast(err error) bool { |
|
|
func validateCast(err error) bool { |
|
|
if err != nil { |
|
|
|
|
|
log.Println(err) |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
return true |
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
log.Println(err) |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_badType struct {} |
|
|
|
|
|
|
|
|
type VariableType_badType struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_badType) Name() string { |
|
|
func (*VariableType_badType) Name() string { |
|
|
return "unknown type" |
|
|
|
|
|
|
|
|
return "unknown type" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_badType) Validate(s JsonValue) bool { |
|
|
func (*VariableType_badType) Validate(s JsonValue) bool { |
|
|
return false |
|
|
|
|
|
|
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_badType) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (*VariableType_badType) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
return template.HTML(""), errors.New("unknown type") |
|
|
|
|
|
|
|
|
return template.HTML(""), errors.New("unknown type") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_badType) DefaultValue() JsonValue { |
|
|
func (*VariableType_badType) DefaultValue() JsonValue { |
|
|
return "" |
|
|
|
|
|
|
|
|
return "" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_bool struct {} |
|
|
|
|
|
|
|
|
type VariableType_bool struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_bool) Name() string { |
|
|
func (*VariableType_bool) Name() string { |
|
|
return "bool" |
|
|
|
|
|
|
|
|
return "bool" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_bool) ToBool(value JsonValue) (bool, error) { |
|
|
func (*VariableType_bool) ToBool(value JsonValue) (bool, error) { |
|
|
val, isBool := value.(bool) |
|
|
|
|
|
if !isBool { |
|
|
|
|
|
return false, errors.New("Non boolean value") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, isBool := value.(bool) |
|
|
|
|
|
if !isBool { |
|
|
|
|
|
return false, errors.New("Non boolean value") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return val, nil |
|
|
|
|
|
|
|
|
return val, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_bool) Validate(value JsonValue) bool { |
|
|
func (self *VariableType_bool) Validate(value JsonValue) bool { |
|
|
_, err := self.ToBool(value) |
|
|
|
|
|
return validateCast(err) |
|
|
|
|
|
|
|
|
_, err := self.ToBool(value) |
|
|
|
|
|
return validateCast(err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_bool) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *VariableType_bool) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
val, err := self.ToBool(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, err := self.ToBool(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret := `<input type="checkbox"` |
|
|
|
|
|
if(val) { |
|
|
|
|
|
ret += ` checked` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `/>` |
|
|
|
|
|
|
|
|
ret := `<input type="checkbox"` |
|
|
|
|
|
if val { |
|
|
|
|
|
ret += ` checked` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `/>` |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_bool) DefaultValue() JsonValue { |
|
|
func (self *VariableType_bool) DefaultValue() JsonValue { |
|
|
return false |
|
|
|
|
|
|
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_int struct {} |
|
|
|
|
|
|
|
|
type VariableType_int struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_int) Name() string { |
|
|
func (*VariableType_int) Name() string { |
|
|
return "int" |
|
|
|
|
|
|
|
|
return "int" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_int) ToInt(value JsonValue) (int64, error) { |
|
|
func (self *VariableType_int) ToInt(value JsonValue) (int64, error) { |
|
|
val, isInt := value.(int64) |
|
|
|
|
|
if !isInt { |
|
|
|
|
|
val2, isInt := value.(int) |
|
|
|
|
|
if isInt { |
|
|
|
|
|
val = int64(val2) |
|
|
|
|
|
} else { |
|
|
|
|
|
return 0, errors.New("Bad int type: " + fmt.Sprintf("%T", value)) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, isInt := value.(int64) |
|
|
|
|
|
if !isInt { |
|
|
|
|
|
val2, isInt := value.(int) |
|
|
|
|
|
if isInt { |
|
|
|
|
|
val = int64(val2) |
|
|
|
|
|
} else { |
|
|
|
|
|
return 0, errors.New("Bad int type: " + fmt.Sprintf("%T", value)) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return val, nil |
|
|
|
|
|
|
|
|
return val, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_int) Validate(value JsonValue) bool { |
|
|
func (self *VariableType_int) Validate(value JsonValue) bool { |
|
|
_, err := self.ToInt(value) |
|
|
|
|
|
return validateCast(err) |
|
|
|
|
|
|
|
|
_, err := self.ToInt(value) |
|
|
|
|
|
return validateCast(err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_int) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *VariableType_int) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
val, err := self.ToInt(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, err := self.ToInt(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret := `<input type="number" step="1" value="` + strconv.FormatInt(val, 10) + `"/>` |
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
ret := `<input type="number" step="1" value="` + strconv.FormatInt(val, 10) + `"/>` |
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_int) DefaultValue() JsonValue { |
|
|
func (self *VariableType_int) DefaultValue() JsonValue { |
|
|
return 0 |
|
|
|
|
|
|
|
|
return 0 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_float struct {} |
|
|
|
|
|
|
|
|
type VariableType_float struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_float) Name() string { |
|
|
func (*VariableType_float) Name() string { |
|
|
return "float" |
|
|
|
|
|
|
|
|
return "float" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_float) ToFloat(value JsonValue) (float64, error) { |
|
|
func (*VariableType_float) ToFloat(value JsonValue) (float64, error) { |
|
|
val, isFloat := value.(float64) |
|
|
|
|
|
if !isFloat { |
|
|
|
|
|
return 0.0, errors.New("Not a float") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, isFloat := value.(float64) |
|
|
|
|
|
if !isFloat { |
|
|
|
|
|
return 0.0, errors.New("Not a float") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return val, nil |
|
|
|
|
|
|
|
|
return val, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_float) Validate(value JsonValue) bool { |
|
|
func (self *VariableType_float) Validate(value JsonValue) bool { |
|
|
_, err := self.ToFloat(value) |
|
|
|
|
|
return validateCast(err) |
|
|
|
|
|
|
|
|
_, err := self.ToFloat(value) |
|
|
|
|
|
return validateCast(err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_float) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *VariableType_float) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
val, err := self.ToFloat(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, err := self.ToFloat(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret := `<input type="number" value="` + strconv.FormatFloat(val, 'g', -1, 64) + `"/>` |
|
|
|
|
|
|
|
|
ret := `<input type="number" value="` + strconv.FormatFloat(val, 'g', -1, 64) + `"/>` |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_float) DefaultValue() JsonValue { |
|
|
func (self *VariableType_float) DefaultValue() JsonValue { |
|
|
return 0.0 |
|
|
|
|
|
|
|
|
return 0.0 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_string struct {} |
|
|
|
|
|
|
|
|
type VariableType_string struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_string) Name() string { |
|
|
func (*VariableType_string) Name() string { |
|
|
return "string" |
|
|
|
|
|
|
|
|
return "string" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_string) ToString(value JsonValue) (string, error) { |
|
|
func (self *VariableType_string) ToString(value JsonValue) (string, error) { |
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return "", errors.New("Not a string") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return "", errors.New("Not a string") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return val, nil |
|
|
|
|
|
|
|
|
return val, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_string) Validate(value JsonValue) bool { |
|
|
func (self *VariableType_string) Validate(value JsonValue) bool { |
|
|
_, err := self.ToString(value) |
|
|
|
|
|
return validateCast(err) |
|
|
|
|
|
|
|
|
_, err := self.ToString(value) |
|
|
|
|
|
return validateCast(err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_string) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *VariableType_string) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
str, err := self.ToString(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
str, err := self.ToString(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret := `<input type="text" value="` + template.HTMLEscapeString(str) + `"/>` |
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
ret := `<input type="text" value="` + template.HTMLEscapeString(str) + `"/>` |
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_string) DefaultValue() JsonValue { |
|
|
func (self *VariableType_string) DefaultValue() JsonValue { |
|
|
return "" |
|
|
|
|
|
|
|
|
return "" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type VariableType_d struct {} |
|
|
|
|
|
|
|
|
type VariableType_d struct{} |
|
|
|
|
|
|
|
|
func (*VariableType_d) Name() string { |
|
|
func (*VariableType_d) Name() string { |
|
|
return "d" |
|
|
|
|
|
|
|
|
return "d" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (*VariableType_d) Validate(value JsonValue) bool { |
|
|
func (*VariableType_d) Validate(value JsonValue) bool { |
|
|
//FIXME
|
|
|
|
|
|
return false |
|
|
|
|
|
|
|
|
//FIXME
|
|
|
|
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_d) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *VariableType_d) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
//FIXME: non-generic version
|
|
|
|
|
|
ret := `<input type="text" value="` /*+ template.HTMLEscapeString(value)*/ +`"/>` |
|
|
|
|
|
|
|
|
//FIXME: non-generic version
|
|
|
|
|
|
ret := `<input type="text" value="` /*+ template.HTMLEscapeString(value)*/ + `"/>` |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *VariableType_d) DefaultValue() JsonValue { |
|
|
func (self *VariableType_d) DefaultValue() JsonValue { |
|
|
//FIXME: non-generic version
|
|
|
|
|
|
return "" |
|
|
|
|
|
|
|
|
//FIXME: non-generic version
|
|
|
|
|
|
return "" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func makeVariableType(s string) VariableType { |
|
|
func makeVariableType(s string) VariableType { |
|
|
switch(strings.ToLower(s)) { |
|
|
|
|
|
case "bool": |
|
|
|
|
|
return &VariableType_bool{} |
|
|
|
|
|
case "int": |
|
|
|
|
|
return &VariableType_int{} |
|
|
|
|
|
case "float": |
|
|
|
|
|
return &VariableType_float{} |
|
|
|
|
|
case "string": |
|
|
|
|
|
return &VariableType_string{} |
|
|
|
|
|
case "d": |
|
|
|
|
|
return &VariableType_d{} |
|
|
|
|
|
default: |
|
|
|
|
|
log.Println("Unknown type:", s) |
|
|
|
|
|
return &VariableType_badType{} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
switch strings.ToLower(s) { |
|
|
|
|
|
case "bool": |
|
|
|
|
|
return &VariableType_bool{} |
|
|
|
|
|
case "int": |
|
|
|
|
|
return &VariableType_int{} |
|
|
|
|
|
case "float": |
|
|
|
|
|
return &VariableType_float{} |
|
|
|
|
|
case "string": |
|
|
|
|
|
return &VariableType_string{} |
|
|
|
|
|
case "d": |
|
|
|
|
|
return &VariableType_d{} |
|
|
|
|
|
default: |
|
|
|
|
|
log.Println("Unknown type:", s) |
|
|
|
|
|
return &VariableType_badType{} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type CustomEnum struct { |
|
|
type CustomEnum struct { |
|
|
name string |
|
|
|
|
|
Values []string |
|
|
|
|
|
|
|
|
name string |
|
|
|
|
|
Values []string |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomEnum) Name() string { |
|
|
func (self *CustomEnum) Name() string { |
|
|
return self.name |
|
|
|
|
|
|
|
|
return self.name |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomEnum) ToId(value JsonValue) (int, error) { |
|
|
func (self *CustomEnum) ToId(value JsonValue) (int, error) { |
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return 0, errors.New("Enum value not a string") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return 0, errors.New("Enum value not a string") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for i := 0; i < len(self.Values); i++ { |
|
|
|
|
|
if self.Values[i] == val { |
|
|
|
|
|
return i, nil |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for i := 0; i < len(self.Values); i++ { |
|
|
|
|
|
if self.Values[i] == val { |
|
|
|
|
|
return i, nil |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return 0, errors.New("No such element") |
|
|
|
|
|
|
|
|
return 0, errors.New("No such element") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomEnum) Validate(value JsonValue) bool { |
|
|
func (self *CustomEnum) Validate(value JsonValue) bool { |
|
|
_, err := self.ToId(value) |
|
|
|
|
|
return validateCast(err) |
|
|
|
|
|
|
|
|
_, err := self.ToId(value) |
|
|
|
|
|
return validateCast(err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomEnum) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *CustomEnum) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return template.HTML(""), errors.New("Bad enum value") |
|
|
|
|
|
} |
|
|
|
|
|
selectItem := val != "" |
|
|
|
|
|
|
|
|
|
|
|
value_id := 0 |
|
|
|
|
|
if selectItem { |
|
|
|
|
|
var err error |
|
|
|
|
|
value_id, err = self.ToId(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ret := `<select>` |
|
|
|
|
|
for i, v := range(self.Values) { |
|
|
|
|
|
ret += `<option` |
|
|
|
|
|
if selectItem && i == value_id { |
|
|
|
|
|
ret += ` selected` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `>` |
|
|
|
|
|
ret += template.HTMLEscapeString(v) |
|
|
|
|
|
ret += `</option>` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `</select>` |
|
|
|
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
|
|
|
|
|
|
val, isString := value.(string) |
|
|
|
|
|
if !isString { |
|
|
|
|
|
return template.HTML(""), errors.New("Bad enum value") |
|
|
|
|
|
} |
|
|
|
|
|
selectItem := val != "" |
|
|
|
|
|
|
|
|
|
|
|
value_id := 0 |
|
|
|
|
|
if selectItem { |
|
|
|
|
|
var err error |
|
|
|
|
|
value_id, err = self.ToId(value) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ret := `<select>` |
|
|
|
|
|
for i, v := range self.Values { |
|
|
|
|
|
ret += `<option` |
|
|
|
|
|
if selectItem && i == value_id { |
|
|
|
|
|
ret += ` selected` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `>` |
|
|
|
|
|
ret += template.HTMLEscapeString(v) |
|
|
|
|
|
ret += `</option>` |
|
|
|
|
|
} |
|
|
|
|
|
ret += `</select>` |
|
|
|
|
|
|
|
|
|
|
|
return template.HTML(ret), nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomEnum) DefaultValue() JsonValue { |
|
|
func (self *CustomEnum) DefaultValue() JsonValue { |
|
|
return "" |
|
|
|
|
|
|
|
|
return "" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type JsonObject map[string]interface{} |
|
|
type JsonObject map[string]interface{} |
|
|
|
|
|
|
|
|
type CustomStruct struct { |
|
|
type CustomStruct struct { |
|
|
name string |
|
|
|
|
|
Variables []*Variable |
|
|
|
|
|
|
|
|
name string |
|
|
|
|
|
Variables []*Variable |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomStruct) Name() string { |
|
|
func (self *CustomStruct) Name() string { |
|
|
return self.name |
|
|
|
|
|
|
|
|
return self.name |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomStruct) Validate(value JsonValue) bool { |
|
|
func (self *CustomStruct) Validate(value JsonValue) bool { |
|
|
obj, isObj := value.(JsonObject) |
|
|
|
|
|
if !isObj { |
|
|
|
|
|
log.Println("Struct \"" + self.Name() + "\": value is not a JSON object") |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
obj, isObj := value.(JsonObject) |
|
|
|
|
|
if !isObj { |
|
|
|
|
|
log.Println("Struct \"" + self.Name() + "\": value is not a JSON object") |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
if !v.Type.Validate(obj[v.Name()]) { |
|
|
|
|
|
log.Println("Struct \"" + self.Name() + "\": value \"" + v.Name() + "\" was not validated") |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
if !v.Type.Validate(obj[v.Name()]) { |
|
|
|
|
|
log.Println("Struct \"" + self.Name() + "\": value \"" + v.Name() + "\" was not validated") |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return true |
|
|
|
|
|
|
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomStruct) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
func (self *CustomStruct) ToHTML(value JsonValue) (template.HTML, error) { |
|
|
if !self.Validate(value) { |
|
|
|
|
|
return template.HTML(""), errors.New("Cannot validate struct") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if !self.Validate(value) { |
|
|
|
|
|
return template.HTML(""), errors.New("Cannot validate struct") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
obj, _ := value.(JsonObject) |
|
|
|
|
|
|
|
|
obj, _ := value.(JsonObject) |
|
|
|
|
|
|
|
|
ret := template.HTML("") |
|
|
|
|
|
ret += `<div>` //FIXME: better tag
|
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
if v.Name() != "" { |
|
|
|
|
|
label := `<label>` + template.HTMLEscapeString(v.Name()) + `</label>` |
|
|
|
|
|
ret += template.HTML(label) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret := template.HTML("") |
|
|
|
|
|
ret += `<div>` //FIXME: better tag
|
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
if v.Name() != "" { |
|
|
|
|
|
label := `<label>` + template.HTMLEscapeString(v.Name()) + `</label>` |
|
|
|
|
|
ret += template.HTML(label) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
html, err := v.Type.ToHTML(obj[v.Name()]) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
html, err := v.Type.ToHTML(obj[v.Name()]) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return template.HTML(""), err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
ret += html |
|
|
|
|
|
} |
|
|
|
|
|
ret += `</div>` |
|
|
|
|
|
|
|
|
ret += html |
|
|
|
|
|
} |
|
|
|
|
|
ret += `</div>` |
|
|
|
|
|
|
|
|
return ret, nil |
|
|
|
|
|
|
|
|
return ret, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (self *CustomStruct) DefaultValue() JsonValue { |
|
|
func (self *CustomStruct) DefaultValue() JsonValue { |
|
|
ret := make(JsonObject) |
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
ret[v.Name()] = v.Type.DefaultValue() |
|
|
|
|
|
} |
|
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
ret := make(JsonObject) |
|
|
|
|
|
for _, v := range self.Variables { |
|
|
|
|
|
ret[v.Name()] = v.Type.DefaultValue() |
|
|
|
|
|
} |
|
|
|
|
|
return ret |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func parseCustomEnum(root xmlNode) (*CustomEnum, error) { |
|
|
func parseCustomEnum(root xmlNode) (*CustomEnum, error) { |
|
|
customEnum := CustomEnum {} |
|
|
|
|
|
|
|
|
customEnum := CustomEnum{} |
|
|
|
|
|
|
|
|
nameOk := false; |
|
|
|
|
|
for i := 0; i < len(root.Attrs); i++ { |
|
|
|
|
|
attrName := root.Attrs[i].Name.Local |
|
|
|
|
|
attrVal := root.Attrs[i].Value |
|
|
|
|
|
|
|
|
nameOk := false |
|
|
|
|
|
for i := 0; i < len(root.Attrs); i++ { |
|
|
|
|
|
attrName := root.Attrs[i].Name.Local |
|
|
|
|
|
attrVal := root.Attrs[i].Value |
|
|
|
|
|
|
|
|
switch attrName { |
|
|
|
|
|
case "name": |
|
|
|
|
|
nameOk = true |
|
|
|
|
|
customEnum.name = attrVal |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
switch attrName { |
|
|
|
|
|
case "name": |
|
|
|
|
|
nameOk = true |
|
|
|
|
|
customEnum.name = attrVal |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if !nameOk { |
|
|
|
|
|
return nil, errors.New("Unnamed custom enum") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if !nameOk { |
|
|
|
|
|
return nil, errors.New("Unnamed custom enum") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "value": |
|
|
|
|
|
customEnum.Values = append(customEnum.Values, string(node.Content)) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "value": |
|
|
|
|
|
customEnum.Values = append(customEnum.Values, string(node.Content)) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return &customEnum, nil |
|
|
|
|
|
|
|
|
return &customEnum, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func parseCustomStruct(root xmlNode, sheet *CharacterSheet) (*CustomStruct, error) { |
|
|
func parseCustomStruct(root xmlNode, sheet *CharacterSheet) (*CustomStruct, error) { |
|
|
customType := CustomStruct{} |
|
|
|
|
|
|
|
|
|
|
|
nameOk := false |
|
|
|
|
|
for i := 0; i < len(root.Attrs); i++ { |
|
|
|
|
|
attrName := root.Attrs[i].Name.Local |
|
|
|
|
|
attrVal := root.Attrs[i].Value |
|
|
|
|
|
|
|
|
|
|
|
switch attrName { |
|
|
|
|
|
case "name": |
|
|
|
|
|
nameOk = true |
|
|
|
|
|
customType.name = attrVal |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !nameOk { |
|
|
|
|
|
return nil, errors.New("Unnamed custom type") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "variable": |
|
|
|
|
|
variable, err := parseVariable(node, sheet, nil) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return nil, err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
customType.Variables = append(customType.Variables, variable) |
|
|
|
|
|
default: |
|
|
|
|
|
return nil, errors.New("Unknown tag in custom type: " + node.XMLName.Local) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return &customType, nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func parseCustomTypes(root xmlNode, sheet *CharacterSheet) (error) { |
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "enum": |
|
|
|
|
|
customEnum, err := parseCustomEnum(node) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
sheet.AddType(customEnum) |
|
|
|
|
|
case "type": |
|
|
|
|
|
customType, err := parseCustomStruct(node, sheet) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
sheet.AddType(customType) |
|
|
|
|
|
default: |
|
|
|
|
|
return errors.New("Unknown CustomType: " + root.Nodes[i].XMLName.Local) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
|
customType := CustomStruct{} |
|
|
|
|
|
|
|
|
|
|
|
nameOk := false |
|
|
|
|
|
for i := 0; i < len(root.Attrs); i++ { |
|
|
|
|
|
attrName := root.Attrs[i].Name.Local |
|
|
|
|
|
attrVal := root.Attrs[i].Value |
|
|
|
|
|
|
|
|
|
|
|
switch attrName { |
|
|
|
|
|
case "name": |
|
|
|
|
|
nameOk = true |
|
|
|
|
|
customType.name = attrVal |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !nameOk { |
|
|
|
|
|
return nil, errors.New("Unnamed custom type") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "variable": |
|
|
|
|
|
variable, err := parseVariable(node, sheet, nil) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return nil, err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
customType.Variables = append(customType.Variables, variable) |
|
|
|
|
|
default: |
|
|
|
|
|
return nil, errors.New("Unknown tag in custom type: " + node.XMLName.Local) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return &customType, nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func parseCustomTypes(root xmlNode, sheet *CharacterSheet) error { |
|
|
|
|
|
for i := 0; i < len(root.Nodes); i++ { |
|
|
|
|
|
node := root.Nodes[i] |
|
|
|
|
|
|
|
|
|
|
|
switch node.XMLName.Local { |
|
|
|
|
|
case "enum": |
|
|
|
|
|
customEnum, err := parseCustomEnum(node) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
sheet.AddType(customEnum) |
|
|
|
|
|
case "type": |
|
|
|
|
|
customType, err := parseCustomStruct(node, sheet) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
sheet.AddType(customType) |
|
|
|
|
|
default: |
|
|
|
|
|
return errors.New("Unknown CustomType: " + root.Nodes[i].XMLName.Local) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
} |
|
|
} |