...

Source file src/github.com/go-openapi/jsonreference/reference.go

Documentation: github.com/go-openapi/jsonreference

     1  // Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //   http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // author       sigu-399
    16  // author-github  https://github.com/sigu-399
    17  // author-mail    sigu.399@gmail.com
    18  //
    19  // repository-name  jsonreference
    20  // repository-desc  An implementation of JSON Reference - Go language
    21  //
    22  // description    Main and unique file.
    23  //
    24  // created        26-02-2013
    25  
    26  package jsonreference
    27  
    28  import (
    29  	"errors"
    30  	"net/url"
    31  	"strings"
    32  
    33  	"github.com/go-openapi/jsonpointer"
    34  	"github.com/go-openapi/jsonreference/internal"
    35  )
    36  
    37  const (
    38  	fragmentRune = `#`
    39  )
    40  
    41  // New creates a new reference for the given string
    42  func New(jsonReferenceString string) (Ref, error) {
    43  
    44  	var r Ref
    45  	err := r.parse(jsonReferenceString)
    46  	return r, err
    47  
    48  }
    49  
    50  // MustCreateRef parses the ref string and panics when it's invalid.
    51  // Use the New method for a version that returns an error
    52  func MustCreateRef(ref string) Ref {
    53  	r, err := New(ref)
    54  	if err != nil {
    55  		panic(err)
    56  	}
    57  	return r
    58  }
    59  
    60  // Ref represents a json reference object
    61  type Ref struct {
    62  	referenceURL     *url.URL
    63  	referencePointer jsonpointer.Pointer
    64  
    65  	HasFullURL      bool
    66  	HasURLPathOnly  bool
    67  	HasFragmentOnly bool
    68  	HasFileScheme   bool
    69  	HasFullFilePath bool
    70  }
    71  
    72  // GetURL gets the URL for this reference
    73  func (r *Ref) GetURL() *url.URL {
    74  	return r.referenceURL
    75  }
    76  
    77  // GetPointer gets the json pointer for this reference
    78  func (r *Ref) GetPointer() *jsonpointer.Pointer {
    79  	return &r.referencePointer
    80  }
    81  
    82  // String returns the best version of the url for this reference
    83  func (r *Ref) String() string {
    84  
    85  	if r.referenceURL != nil {
    86  		return r.referenceURL.String()
    87  	}
    88  
    89  	if r.HasFragmentOnly {
    90  		return fragmentRune + r.referencePointer.String()
    91  	}
    92  
    93  	return r.referencePointer.String()
    94  }
    95  
    96  // IsRoot returns true if this reference is a root document
    97  func (r *Ref) IsRoot() bool {
    98  	return r.referenceURL != nil &&
    99  		!r.IsCanonical() &&
   100  		!r.HasURLPathOnly &&
   101  		r.referenceURL.Fragment == ""
   102  }
   103  
   104  // IsCanonical returns true when this pointer starts with http(s):// or file://
   105  func (r *Ref) IsCanonical() bool {
   106  	return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL)
   107  }
   108  
   109  // "Constructor", parses the given string JSON reference
   110  func (r *Ref) parse(jsonReferenceString string) error {
   111  
   112  	parsed, err := url.Parse(jsonReferenceString)
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	internal.NormalizeURL(parsed)
   118  
   119  	r.referenceURL = parsed
   120  	refURL := r.referenceURL
   121  
   122  	if refURL.Scheme != "" && refURL.Host != "" {
   123  		r.HasFullURL = true
   124  	} else {
   125  		if refURL.Path != "" {
   126  			r.HasURLPathOnly = true
   127  		} else if refURL.RawQuery == "" && refURL.Fragment != "" {
   128  			r.HasFragmentOnly = true
   129  		}
   130  	}
   131  
   132  	r.HasFileScheme = refURL.Scheme == "file"
   133  	r.HasFullFilePath = strings.HasPrefix(refURL.Path, "/")
   134  
   135  	// invalid json-pointer error means url has no json-pointer fragment. simply ignore error
   136  	r.referencePointer, _ = jsonpointer.New(refURL.Fragment)
   137  
   138  	return nil
   139  }
   140  
   141  // Inherits creates a new reference from a parent and a child
   142  // If the child cannot inherit from the parent, an error is returned
   143  func (r *Ref) Inherits(child Ref) (*Ref, error) {
   144  	childURL := child.GetURL()
   145  	parentURL := r.GetURL()
   146  	if childURL == nil {
   147  		return nil, errors.New("child url is nil")
   148  	}
   149  	if parentURL == nil {
   150  		return &child, nil
   151  	}
   152  
   153  	ref, err := New(parentURL.ResolveReference(childURL).String())
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return &ref, nil
   158  }
   159  

View as plain text