Skip to content

Commit

Permalink
Merge pull request #103 from yuichi1004/topic/implement_json_loader_i…
Browse files Browse the repository at this point in the history
…nterface

Make JSONLoader public to support cusotm json loader
  • Loading branch information
xeipuuv authored Jun 20, 2016
2 parents d5336c7 + ac948b6 commit 8029392
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 99 deletions.
153 changes: 62 additions & 91 deletions jsonLoader.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,38 @@ var osFS = osFileSystem(os.Open)
// JSON loader interface

type JSONLoader interface {
jsonSource() interface{}
loadJSON() (interface{}, error)
loadSchema() (*Schema, error)
JsonSource() interface{}
LoadJSON() (interface{}, error)
JsonReference() (gojsonreference.JsonReference, error)
LoaderFactory() JSONLoaderFactory
}

type JSONLoaderFactory interface {
New(source string) JSONLoader
}

type DefaultJSONLoaderFactory struct {
}

type FileSystemJSONLoaderFactory struct {
fs http.FileSystem
}

func (d DefaultJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: osFS,
source: source,
}
}

func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: f.fs,
source: source,
}
}


// osFileSystem is a functional wrapper for os.Open that implements http.FileSystem.
type osFileSystem func(string) (*os.File, error)

Expand All @@ -66,10 +93,18 @@ type jsonReferenceLoader struct {
source string
}

func (l *jsonReferenceLoader) jsonSource() interface{} {
func (l *jsonReferenceLoader) JsonSource() interface{} {
return l.source
}

func (l *jsonReferenceLoader) JsonReference() (gojsonreference.JsonReference, error) {
return gojsonreference.NewJsonReference(l.JsonSource().(string))
}

func (l *jsonReferenceLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}

// NewReferenceLoader returns a JSON reference loader using the given source and the local OS file system.
func NewReferenceLoader(source string) *jsonReferenceLoader {
return &jsonReferenceLoader{
Expand All @@ -86,11 +121,11 @@ func NewReferenceLoaderFileSystem(source string, fs http.FileSystem) *jsonRefere
}
}

func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {
func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) {

var err error

reference, err := gojsonreference.NewJsonReference(l.jsonSource().(string))
reference, err := gojsonreference.NewJsonReference(l.JsonSource().(string))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -131,32 +166,6 @@ func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {

}

func (l *jsonReferenceLoader) loadSchema() (*Schema, error) {

var err error

d := Schema{}
d.pool = newSchemaPool(l.fs)
d.referencePool = newSchemaReferencePool()

d.documentReference, err = gojsonreference.NewJsonReference(l.jsonSource().(string))
if err != nil {
return nil, err
}

spd, err := d.pool.GetDocument(d.documentReference)
if err != nil {
return nil, err
}

err = d.parse(spd.Document)
if err != nil {
return nil, err
}

return &d, nil

}

func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) {

Expand Down Expand Up @@ -201,44 +210,25 @@ type jsonStringLoader struct {
source string
}

func (l *jsonStringLoader) jsonSource() interface{} {
func (l *jsonStringLoader) JsonSource() interface{} {
return l.source
}

func NewStringLoader(source string) *jsonStringLoader {
return &jsonStringLoader{source: source}
func (l *jsonStringLoader) JsonReference() (gojsonreference.JsonReference, error) {
return gojsonreference.NewJsonReference("#")
}

func (l *jsonStringLoader) loadJSON() (interface{}, error) {

return decodeJsonUsingNumber(strings.NewReader(l.jsonSource().(string)))

func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}

func (l *jsonStringLoader) loadSchema() (*Schema, error) {

var err error

document, err := l.loadJSON()
if err != nil {
return nil, err
}

d := Schema{}
d.pool = newSchemaPool(osFS)
d.referencePool = newSchemaReferencePool()
d.documentReference, err = gojsonreference.NewJsonReference("#")
d.pool.SetStandaloneDocument(document)
if err != nil {
return nil, err
}
func NewStringLoader(source string) *jsonStringLoader {
return &jsonStringLoader{source: source}
}

err = d.parse(document)
if err != nil {
return nil, err
}
func (l *jsonStringLoader) LoadJSON() (interface{}, error) {

return &d, nil
return decodeJsonUsingNumber(strings.NewReader(l.JsonSource().(string)))

}

Expand All @@ -249,19 +239,27 @@ type jsonGoLoader struct {
source interface{}
}

func (l *jsonGoLoader) jsonSource() interface{} {
func (l *jsonGoLoader) JsonSource() interface{} {
return l.source
}

func (l *jsonGoLoader) JsonReference() (gojsonreference.JsonReference, error) {
return gojsonreference.NewJsonReference("#")
}

func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}

func NewGoLoader(source interface{}) *jsonGoLoader {
return &jsonGoLoader{source: source}
}

func (l *jsonGoLoader) loadJSON() (interface{}, error) {
func (l *jsonGoLoader) LoadJSON() (interface{}, error) {

// convert it to a compliant JSON first to avoid types "mismatches"

jsonBytes, err := json.Marshal(l.jsonSource())
jsonBytes, err := json.Marshal(l.JsonSource())
if err != nil {
return nil, err
}
Expand All @@ -270,33 +268,6 @@ func (l *jsonGoLoader) loadJSON() (interface{}, error) {

}

func (l *jsonGoLoader) loadSchema() (*Schema, error) {

var err error

document, err := l.loadJSON()
if err != nil {
return nil, err
}

d := Schema{}
d.pool = newSchemaPool(osFS)
d.referencePool = newSchemaReferencePool()
d.documentReference, err = gojsonreference.NewJsonReference("#")
d.pool.SetStandaloneDocument(document)
if err != nil {
return nil, err
}

err = d.parse(document)
if err != nil {
return nil, err
}

return &d, nil

}

func decodeJsonUsingNumber(r io.Reader) (interface{}, error) {

var document interface{}
Expand Down
34 changes: 33 additions & 1 deletion schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,39 @@ var (
)

func NewSchema(l JSONLoader) (*Schema, error) {
return l.loadSchema()
ref, err := l.JsonReference()
if err != nil {
return nil, err
}

d := Schema{}
d.pool = newSchemaPool(l.LoaderFactory())
d.documentReference = ref
d.referencePool=newSchemaReferencePool()

var doc interface{}
if ref.String() != "#" {
// Get document from schema pool
spd, err := d.pool.GetDocument(d.documentReference)
if err != nil {
return nil, err
}
doc = spd.Document
} else {
// Load JSON directly
doc, err = l.LoadJSON()
if err != nil {
return nil, err
}
d.pool.SetStandaloneDocument(doc)
}

err = d.parse(doc)
if err != nil {
return nil, err
}

return &d, nil
}

type Schema struct {
Expand Down
11 changes: 5 additions & 6 deletions schemaPool.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ package gojsonschema

import (
"errors"
"net/http"

"github.com/xeipuuv/gojsonreference"
)
Expand All @@ -40,15 +39,15 @@ type schemaPoolDocument struct {
type schemaPool struct {
schemaPoolDocuments map[string]*schemaPoolDocument
standaloneDocument interface{}
fs http.FileSystem
jsonLoaderFactory JSONLoaderFactory
}

func newSchemaPool(fs http.FileSystem) *schemaPool {
func newSchemaPool(f JSONLoaderFactory) *schemaPool {

p := &schemaPool{}
p.schemaPoolDocuments = make(map[string]*schemaPoolDocument)
p.standaloneDocument = nil
p.fs = fs
p.jsonLoaderFactory = f

return p
}
Expand Down Expand Up @@ -96,8 +95,8 @@ func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*sche
return spd, nil
}

jsonReferenceLoader := NewReferenceLoaderFileSystem(reference.String(), p.fs)
document, err := jsonReferenceLoader.loadJSON()
jsonReferenceLoader := p.jsonLoaderFactory.New(reference.String())
document, err := jsonReferenceLoader.LoadJSON()
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (v *Schema) Validate(l JSONLoader) (*Result, error) {

// load document

root, err := l.loadJSON()
root, err := l.LoadJSON()
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 8029392

Please sign in to comment.