libs5-go/metadata/web_app.go

297 lines
5.6 KiB
Go

package metadata
import (
"errors"
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
"git.lumeweb.com/LumeWeb/libs5-go/serialize"
"git.lumeweb.com/LumeWeb/libs5-go/types"
"github.com/emirpasic/gods/maps/linkedhashmap"
"github.com/vmihailenco/msgpack/v5"
"sort"
)
var (
_ Metadata = (*WebAppMetadata)(nil)
_ SerializableMetadata = (*WebAppMetadata)(nil)
_ SerializableMetadata = (*WebAppFileMap)(nil)
_ SerializableMetadata = (*WebAppErrorPages)(nil)
)
type WebAppErrorPages map[int]string
type WebAppMetadata struct {
BaseMetadata
Name string `json:"name"`
TryFiles []string `json:"tryFiles"`
ErrorPages WebAppErrorPages `json:"errorPages"`
ExtraMetadata ExtraMetadata `json:"extraMetadata"`
Paths *WebAppFileMap `json:"paths"`
}
func NewWebAppMetadata(name string, tryFiles []string, extraMetadata ExtraMetadata, errorPages WebAppErrorPages, paths *WebAppFileMap) *WebAppMetadata {
return &WebAppMetadata{
Name: name,
TryFiles: tryFiles,
ExtraMetadata: extraMetadata,
ErrorPages: errorPages,
Paths: paths,
}
}
func NewEmptyWebAppMetadata() *WebAppMetadata {
return &WebAppMetadata{}
}
func (wm *WebAppMetadata) EncodeMsgpack(enc *msgpack.Encoder) error {
err := serialize.InitMarshaller(enc, types.MetadataTypeWebApp)
if err != nil {
return err
}
items := make([]interface{}, 5)
if wm.ErrorPages == nil {
wm.ErrorPages = make(WebAppErrorPages)
}
items[0] = wm.Name
items[1] = wm.TryFiles
items[2] = &wm.ErrorPages
items[3] = wm.Paths
items[4] = wm.ExtraMetadata
return enc.Encode(items)
}
func (wm *WebAppMetadata) DecodeMsgpack(dec *msgpack.Decoder) error {
_, err := serialize.InitUnmarshaller(dec, types.MetadataTypeWebApp)
if err != nil {
return err
}
val, err := dec.DecodeArrayLen()
if err != nil {
return err
}
if val != 5 {
return errors.New(" Corrupted metadata")
}
for i := 0; i < val; i++ {
switch i {
case 0:
wm.Name, err = dec.DecodeString()
if err != nil {
return err
}
case 1:
err = dec.Decode(&wm.TryFiles)
if err != nil {
return err
}
case 2:
err = dec.Decode(&wm.ErrorPages)
if err != nil {
return err
}
case 3:
err = dec.Decode(&wm.Paths)
if err != nil {
return err
}
case 4:
err = dec.Decode(&wm.ExtraMetadata)
if err != nil {
return err
}
default:
return errors.New(" Corrupted metadata")
}
}
wm.Type = "web_app"
return nil
}
type WebAppFileMap struct {
linkedhashmap.Map
}
func NewWebAppFileMap() *WebAppFileMap {
return &WebAppFileMap{*linkedhashmap.New()}
}
func (wafm *WebAppFileMap) Put(key string, value WebAppMetadataFileReference) {
wafm.Map.Put(key, value)
}
func (wafm *WebAppFileMap) Get(key string) (WebAppMetadataFileReference, bool) {
value, found := wafm.Map.Get(key)
if !found {
return WebAppMetadataFileReference{}, false
}
return value.(WebAppMetadataFileReference), true
}
func (wafm *WebAppFileMap) Remove(key string) {
wafm.Map.Remove(key)
}
func (wafm *WebAppFileMap) Keys() []string {
keys := wafm.Map.Keys()
ret := make([]string, len(keys))
for i, key := range keys {
ret[i] = key.(string)
}
return ret
}
func (wafm *WebAppFileMap) Values() []WebAppMetadataFileReference {
values := wafm.Map.Values()
ret := make([]WebAppMetadataFileReference, len(values))
for i, value := range values {
ret[i] = value.(WebAppMetadataFileReference)
}
return ret
}
func (wafm *WebAppFileMap) Sort() {
keys := wafm.Keys()
newMap := NewWebAppFileMap()
sort.Strings(keys)
for _, key := range keys {
value, _ := wafm.Get(key)
newMap.Put(key, value)
}
wafm.Map = newMap.Map
}
func (wafm *WebAppFileMap) EncodeMsgpack(encoder *msgpack.Encoder) error {
wafm.Sort()
err := encoder.EncodeArrayLen(wafm.Size())
if err != nil {
return err
}
for _, key := range wafm.Keys() {
value, _ := wafm.Get(key)
data :=
make([]interface{}, 3)
data[0] = key
data[1] = value.Cid.ToBytes()
data[2] = value.ContentType
err := encoder.Encode(data)
if err != nil {
return err
}
}
return nil
}
func (wafm *WebAppFileMap) DecodeMsgpack(decoder *msgpack.Decoder) error {
arrLen, err := decoder.DecodeArrayLen()
if err != nil {
return err
}
for i := 0; i < arrLen; i++ {
data := make([]interface{}, 3)
if len(data) != 3 {
return errors.New("Corrupted metadata")
}
err = decoder.Decode(&data)
if err != nil {
return err
}
path, ok := data[0].(string)
if !ok {
return errors.New("Corrupted metadata")
}
cidData, ok := data[1].([]byte)
if !ok {
return errors.New("Corrupted metadata")
}
contentType, ok := data[2].(string)
if !ok {
return errors.New("Corrupted metadata")
}
cid, err := encoding.CIDFromBytes(cidData)
if err != nil {
return err
}
wafm.Put(path, *NewWebAppMetadataFileReference(cid, contentType))
}
wafm.Sort()
return nil
}
func (w *WebAppErrorPages) EncodeMsgpack(enc *msgpack.Encoder) error {
if w == nil || *w == nil {
return enc.EncodeMapLen(0)
}
err := enc.EncodeMapLen(len(*w))
if err != nil {
return err
}
for k, v := range *w {
if err := enc.EncodeInt(int64(k)); err != nil {
return err
}
if err := enc.EncodeString(v); err != nil {
return err
}
}
return nil
}
func (w *WebAppErrorPages) DecodeMsgpack(dec *msgpack.Decoder) error {
if *w == nil {
*w = make(map[int]string)
}
mapLen, err := dec.DecodeMapLen()
if err != nil {
return err
}
*w = make(map[int]string, mapLen)
for i := 0; i < mapLen; i++ {
key, err := dec.DecodeInt()
if err != nil {
return err
}
value, err := dec.DecodeString()
if err != nil {
return err
}
(*w)[key] = value
}
return nil
}