Class: URIResolver::URIResolverImplementation

Inherits:
Object
  • Object
show all
Defined in:
backend/app/lib/uri_resolver.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(properties_to_resolve) ⇒ URIResolverImplementation

Returns a new instance of URIResolverImplementation.



80
81
82
# File 'backend/app/lib/uri_resolver.rb', line 80

def initialize(properties_to_resolve)
  @properties_to_resolve = parse_properties(properties_to_resolve)
end

Class Method Details

.register_resolver(resolver) ⇒ Object



88
89
90
# File 'backend/app/lib/uri_resolver.rb', line 88

def self.register_resolver(resolver)
  resolvers.insert(0, resolver)
end

.resolversObject



84
85
86
# File 'backend/app/lib/uri_resolver.rb', line 84

def self.resolvers
  @resolvers ||= [TreeResolver, ASModelResolver]
end

Instance Method Details

#ensure_reference_is_valid(uri, active_repository_id = nil) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'backend/app/lib/uri_resolver.rb', line 92

def ensure_reference_is_valid(uri, active_repository_id = nil)
  parsed = JSONModel.parse_reference(uri)

  # error on anything that points outside the active repository
  if active_repository_id && \
     parsed[:repository] && \
     JSONModel.parse_reference(parsed[:repository])[:id] != active_repository_id

    raise ReferenceError.new("Inter-repository links are not allowed in this operation! (Bad link: '#{uri}'; Active repo: '#/repositories/#{active_repository_id}')")
  end

  resolver = get_resolver_for_type(parsed[:type])

  if resolver && !resolver.record_exists?(uri)
    raise ReferenceError.new("Reference does not exist! (Reference: '#{uri}')")
  end
end

#resolve_references(value) ⇒ Object

Walk ‘value’, find all refs, resolve them



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'backend/app/lib/uri_resolver.rb', line 111

def resolve_references(value)
  return value if @properties_to_resolve.empty?

  # Make sure we have an array, even if there's just one record to resolve
  was_wrapped = false
  if value.is_a?(Array)
    records = value
  else
    records = ASUtils.wrap(value)
    was_wrapped = true
  end

  # Any JSONModels can become vanilla hashes
  records = records.map {|value|
    if value.is_a?(JSONModelType)
      value.to_hash(:trusted)
    else
      value
    end
  }

  # We'll work through our records breadth-first, first resolving non-nested
  # properties, then those that are nested two-levels deep, then
  # three-levels deep, and so on.
  #
  # With each iteration, we try to group together resolve requests for
  # common record types to get as much bang for our SQL buck as possible.
  depth = 1
  while true
    properties_for_current_depth = @properties_to_resolve.select {|property| property.length == depth}

    break if properties_for_current_depth.empty?

    refs_to_resolve = find_matching_refs(records, properties_for_current_depth)

    resolved = fetch_records_by_uri(refs_to_resolve.map {|ref| ref['ref']})

    refs_to_resolve.each do |ref|
      uri = ref['ref']
      ref['_resolved'] = resolved.fetch(uri) if resolved.has_key?(uri)
    end

    depth += 1
  end

  # Return the same type we were given
  was_wrapped ? records[0] : records
end