336 lines
7.3 KiB
Go
336 lines
7.3 KiB
Go
package activitystreams
|
|
|
|
import (
|
|
"encoding"
|
|
"encoding/json"
|
|
"net/url"
|
|
"reflect"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/buger/jsonparser"
|
|
)
|
|
|
|
var (
|
|
apUnmarshalerType = reflect.TypeOf(new(Item)).Elem()
|
|
unmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem()
|
|
textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
|
|
)
|
|
|
|
type mockObj map[string]json.RawMessage
|
|
|
|
func getType(j json.RawMessage) ActivityVocabularyType {
|
|
mock := make(mockObj, 0)
|
|
json.Unmarshal([]byte(j), &mock)
|
|
|
|
for key, val := range mock {
|
|
if strings.ToLower(key) == "type" {
|
|
return ActivityVocabularyType(strings.Trim(string(val), "\""))
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getAPObjectID(data []byte) ObjectID {
|
|
i, err := jsonparser.GetString(data, "id")
|
|
if err != nil {
|
|
return ObjectID("")
|
|
}
|
|
return ObjectID(i)
|
|
}
|
|
|
|
func getAPType(data []byte) ActivityVocabularyType {
|
|
t, err := jsonparser.GetString(data, "type")
|
|
typ := ActivityVocabularyType(t)
|
|
if err != nil {
|
|
return ActivityVocabularyType("")
|
|
}
|
|
return typ
|
|
}
|
|
|
|
func getAPMimeType(data []byte) MimeType {
|
|
t, err := jsonparser.GetString(data, "mediaType")
|
|
if err != nil {
|
|
return MimeType("")
|
|
}
|
|
return MimeType(t)
|
|
}
|
|
func getAPInt(data []byte, prop string) int64 {
|
|
val, err := jsonparser.GetInt(data, prop)
|
|
if err != nil {
|
|
}
|
|
return val
|
|
}
|
|
|
|
func getAPString(data []byte, prop string) string {
|
|
val, err := jsonparser.GetString(data, prop)
|
|
if err != nil {
|
|
}
|
|
return val
|
|
}
|
|
|
|
func getAPNaturalLanguageField(data []byte, prop string) NaturalLanguageValue {
|
|
n := NaturalLanguageValue{}
|
|
val, typ, _, err := jsonparser.Get(data, prop)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
switch typ {
|
|
case jsonparser.Object:
|
|
jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
|
|
if dataType == jsonparser.String {
|
|
n.Append(LangRef(key), string(value))
|
|
}
|
|
return err
|
|
})
|
|
case jsonparser.String:
|
|
n.Append(NilLangRef, string(val))
|
|
}
|
|
|
|
return n
|
|
}
|
|
|
|
func getAPTime(data []byte, prop string) time.Time {
|
|
t := time.Time{}
|
|
str, _ := jsonparser.GetUnsafeString(data, prop)
|
|
t.UnmarshalText([]byte(str))
|
|
return t
|
|
}
|
|
|
|
func unmarshalToAPObject(data []byte) Item {
|
|
if _, err := url.ParseRequestURI(string(data)); err == nil {
|
|
// try to see if it's an IRI
|
|
return IRI(data)
|
|
}
|
|
|
|
i, err := getAPObjectByType(getAPType(data))
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
p := reflect.PtrTo(reflect.TypeOf(i))
|
|
if reflect.TypeOf(i).Implements(unmarshalerType) || p.Implements(unmarshalerType) {
|
|
err = i.(json.Unmarshaler).UnmarshalJSON(data)
|
|
}
|
|
if reflect.TypeOf(i).Implements(textUnmarshalerType) || p.Implements(textUnmarshalerType) {
|
|
err = i.(encoding.TextUnmarshaler).UnmarshalText(data)
|
|
}
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return i
|
|
}
|
|
|
|
func getAPItem(data []byte, prop string) Item {
|
|
val, typ, _, err := jsonparser.Get(data, prop)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
switch typ {
|
|
case jsonparser.String:
|
|
if _, err = url.ParseRequestURI(string(val)); err == nil {
|
|
// try to see if it's an IRI
|
|
return IRI(val)
|
|
}
|
|
case jsonparser.Object:
|
|
return unmarshalToAPObject(val)
|
|
case jsonparser.Number:
|
|
fallthrough
|
|
case jsonparser.Array:
|
|
fallthrough
|
|
case jsonparser.Boolean:
|
|
fallthrough
|
|
case jsonparser.Null:
|
|
fallthrough
|
|
case jsonparser.Unknown:
|
|
fallthrough
|
|
default:
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getAPItems(data []byte, prop string) ItemCollection {
|
|
val, typ, _, err := jsonparser.Get(data, prop)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var it ItemCollection
|
|
switch typ {
|
|
case jsonparser.Array:
|
|
jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
|
|
var i Item
|
|
switch dataType {
|
|
case jsonparser.String:
|
|
if _, err = url.ParseRequestURI(string(val)); err == nil {
|
|
// try to see if it's an IRI
|
|
i = IRI(value)
|
|
}
|
|
case jsonparser.Object:
|
|
i = unmarshalToAPObject(value)
|
|
case jsonparser.Number:
|
|
fallthrough
|
|
case jsonparser.Array:
|
|
fallthrough
|
|
case jsonparser.Boolean:
|
|
fallthrough
|
|
case jsonparser.Null:
|
|
fallthrough
|
|
case jsonparser.Unknown:
|
|
fallthrough
|
|
default:
|
|
return
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
if i != nil {
|
|
it.Append(i)
|
|
}
|
|
}, prop)
|
|
case jsonparser.Object:
|
|
jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
|
|
i := unmarshalToAPObject(value)
|
|
if i != nil {
|
|
it.Append(i)
|
|
}
|
|
return err
|
|
}, prop)
|
|
case jsonparser.String:
|
|
s, _ := jsonparser.GetString(val)
|
|
it.Append(IRI(s))
|
|
}
|
|
return it
|
|
}
|
|
func getAPItemCollection(data []byte, prop string) ItemCollection {
|
|
val, typ, _, err := jsonparser.Get(data, prop)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var it ItemCollection
|
|
switch typ {
|
|
case jsonparser.Array:
|
|
jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
|
|
i, err := getAPObjectByType(getAPType(value))
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = i.(json.Unmarshaler).UnmarshalJSON(value)
|
|
if err != nil {
|
|
return
|
|
}
|
|
it.Append(i)
|
|
}, prop)
|
|
case jsonparser.Object:
|
|
jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
|
|
i := Object{}
|
|
err := i.UnmarshalJSON(val)
|
|
it.Append(i)
|
|
return err
|
|
}, prop)
|
|
case jsonparser.String:
|
|
it.Append(IRI(val))
|
|
}
|
|
|
|
return it
|
|
}
|
|
|
|
func getURIField(data []byte, prop string) Item {
|
|
val, typ, _, err := jsonparser.Get(data, prop)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
switch typ {
|
|
case jsonparser.Object:
|
|
return getAPItem(data, prop)
|
|
case jsonparser.Array:
|
|
var it ItemCollection
|
|
jsonparser.ArrayEach(val, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
|
|
if _, err := url.Parse(string(value)); err == nil {
|
|
it.Append(IRI(value))
|
|
return
|
|
}
|
|
i, err := getAPObjectByType(getAPType(value))
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = i.(json.Unmarshaler).UnmarshalJSON(value)
|
|
if err != nil {
|
|
return
|
|
}
|
|
it.Append(i)
|
|
})
|
|
|
|
return it
|
|
case jsonparser.String:
|
|
return IRI(val)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getAPLangRefField(data []byte, prop string) LangRef {
|
|
val, err := jsonparser.GetString(data, prop)
|
|
if err != nil {
|
|
return LangRef("")
|
|
}
|
|
return LangRef(val)
|
|
}
|
|
|
|
/*
|
|
func unmarshal(data []byte, a interface{}) (interface{}, error) {
|
|
ta := make(mockObj, 0)
|
|
err := jsonld.Unmarshal(data, &ta)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
typ := reflect.TypeOf(a)
|
|
val := reflect.ValueOf(a)
|
|
|
|
if typ.Kind() == reflect.Ptr {
|
|
typ = typ.Elem()
|
|
val = val.Elem()
|
|
}
|
|
|
|
for i := 0; i < typ.NumField(); i++ {
|
|
cField := typ.Field(i)
|
|
cValue := val.Field(i)
|
|
cTag := cField.Tag
|
|
tag, _ := jsonld.LoadTag(cTag)
|
|
|
|
var vv reflect.Value
|
|
for key, j := range ta {
|
|
if j == nil {
|
|
continue
|
|
}
|
|
if key == tag.Name {
|
|
if cField.Type.Implements(textUnmarshalerType) {
|
|
m, _ := cValue.Interface().(encoding.TextUnmarshaler)
|
|
m.UnmarshalText(j)
|
|
vv = reflect.ValueOf(m)
|
|
}
|
|
if cField.Type.Implements(unmarshalerType) {
|
|
m, _ := cValue.Interface().(json.Unmarshaler)
|
|
m.UnmarshalJSON(j)
|
|
vv = reflect.ValueOf(m)
|
|
}
|
|
if cField.Type.Implements(apUnmarshalerType) {
|
|
o := getAPObjectByType(getType(j))
|
|
if o != nil {
|
|
jsonld.Unmarshal([]byte(j), o)
|
|
vv = reflect.ValueOf(o)
|
|
}
|
|
}
|
|
}
|
|
if vv.CanAddr() {
|
|
cValue.Set(vv)
|
|
fmt.Printf("\n\nReflected %q %q => %#v\n\n%#v\n", cField.Name, cField.Type, vv, tag.Name)
|
|
}
|
|
}
|
|
}
|
|
return a, nil
|
|
}
|
|
*/
|