fedora_lens 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +10 -0
- data/README.md +29 -0
- data/Rakefile +19 -0
- data/config/jetty.yml +6 -0
- data/demo.rb +76 -0
- data/fedora/.gitkeep +0 -0
- data/fedora_lens.gemspec +30 -0
- data/lib/fedora_lens/errors.rb +7 -0
- data/lib/fedora_lens/lens.rb +15 -0
- data/lib/fedora_lens/lens_tests.rb +60 -0
- data/lib/fedora_lens/lenses.rb +149 -0
- data/lib/fedora_lens/version.rb +3 -0
- data/lib/fedora_lens.rb +181 -0
- data/lib/ldp_monkeypatch.rb +22 -0
- data/lib/test_class.rb +64 -0
- data/spec/fedora_lens/lenses_spec.rb +87 -0
- data/spec/fedora_lens_spec.rb +107 -0
- data/spec/spec_helper.rb +16 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: af9796406a65d286343ded62b45876a28f2c542f
|
4
|
+
data.tar.gz: c1237758ac4f5fc1131f9add45cbddf5d657c840
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5bfca9e2b65760e3674ceb986153df14f6de8885c320287cd2367ade51aa1ca78cb0d97a824b479871df63e298442b4b49d590c6469b539984a00704cd440d2e
|
7
|
+
data.tar.gz: 9b4fe962ae9a7dc2e70fc9533129b2247e10acd14554247b3ebcdfa25c051f6620f779eadab9f4a3e7c1d4455af4e92c9c57e7e5cd989bf117102d805e3cfbfe
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p353
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
## Usage
|
2
|
+
|
3
|
+
Download and extract Fedora 4:
|
4
|
+
```bash
|
5
|
+
rake jetty:download
|
6
|
+
rake jetty:unzip
|
7
|
+
```
|
8
|
+
|
9
|
+
Start Fedora:
|
10
|
+
```bash
|
11
|
+
rake jetty:start
|
12
|
+
```
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
# bundle console
|
16
|
+
require 'test_class'
|
17
|
+
b = TestClass.new(title: "New resource")
|
18
|
+
b.uri
|
19
|
+
b.save
|
20
|
+
b.id
|
21
|
+
a = TestClass.find(b.id)
|
22
|
+
a.attributes
|
23
|
+
a.primary_id = "some id"
|
24
|
+
a.save
|
25
|
+
b.reload
|
26
|
+
b.attributes
|
27
|
+
c = TestClass.create(title: "created resource")
|
28
|
+
c.id
|
29
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
ZIP_URL = "https://github.com/projecthydra/hydra-jetty/archive/fedora-4a4.zip"
|
9
|
+
require 'jettywrapper'
|
10
|
+
|
11
|
+
task default: :ci
|
12
|
+
|
13
|
+
task ci: 'jetty:unzip' do
|
14
|
+
jetty_params = Jettywrapper.load_config('test')
|
15
|
+
error = Jettywrapper.wrap(jetty_params) do
|
16
|
+
Rake::Task[:spec].invoke
|
17
|
+
end
|
18
|
+
raise "test failures: #{error}" if error
|
19
|
+
end
|
data/config/jetty.yml
ADDED
data/demo.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'fedora_lens'
|
2
|
+
require 'active_support/core_ext/string'
|
3
|
+
|
4
|
+
module GenericFileRdfDatastream
|
5
|
+
def self.mappings
|
6
|
+
{
|
7
|
+
part_of: [RDF::DC.isPartOf],
|
8
|
+
resource_type: [RDF::DC.type],
|
9
|
+
part_of: [RDF::DC.isPartOf],
|
10
|
+
resource_type: [RDF::DC.type],
|
11
|
+
title: [RDF::DC.title],
|
12
|
+
creator: [RDF::DC.creator],
|
13
|
+
contributor: [RDF::DC.contributor],
|
14
|
+
description: [RDF::DC.description],
|
15
|
+
tag: [RDF::DC.relation],
|
16
|
+
rights: [RDF::DC.rights],
|
17
|
+
publisher: [RDF::DC.publisher],
|
18
|
+
date_created: [RDF::DC.created],
|
19
|
+
date_uploaded: [RDF::DC.dateSubmitted],
|
20
|
+
date_modified: [RDF::DC.modified],
|
21
|
+
subject: [RDF::DC.subject],
|
22
|
+
language: [RDF::DC.language],
|
23
|
+
identifier: [RDF::DC.identifier],
|
24
|
+
based_near: [RDF::FOAF.based_near],
|
25
|
+
related_url: [RDF::RDFS.seeAlso],
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Metadata
|
31
|
+
extend ActiveSupport::Concern
|
32
|
+
|
33
|
+
included do
|
34
|
+
# has_metadata "descMetadata", type: GenericFileRdfDatastream
|
35
|
+
# has_metadata "properties", type: PropertiesDatastream
|
36
|
+
# has_file_datastream "content", type: FileContentDatastream
|
37
|
+
# has_file_datastream "thumbnail"
|
38
|
+
|
39
|
+
# has_attributes :relative_path, :depositor, :import_url, datastream: :properties, multiple: false
|
40
|
+
has_attributes :date_uploaded, :date_modified, datastream: :descMetadata, multiple: false
|
41
|
+
has_attributes :related_url, :based_near, :part_of, :creator,
|
42
|
+
:contributor, :title, :tag, :description, :rights,
|
43
|
+
:publisher, :date_created, :subject,
|
44
|
+
:resource_type, :identifier, :language, datastream: :descMetadata, multiple: true
|
45
|
+
end
|
46
|
+
|
47
|
+
def descMetadata
|
48
|
+
{path: [RDF::URI.new('http://digitalcurationexperts.com/example#descMetadata'),
|
49
|
+
FedoraLens::Lenses.single,
|
50
|
+
FedoraLens::Lenses.load_or_build_orm],
|
51
|
+
type: GenericFileRdfDatastream}
|
52
|
+
end
|
53
|
+
def properties
|
54
|
+
{path: [RDF::URI.new('http://digitalcurationexperts.com/example#properties'),
|
55
|
+
FedoraLens::Lenses.single,
|
56
|
+
FedoraLens::Lenses.load_or_build_orm],
|
57
|
+
type: PropertiesDatastream}
|
58
|
+
end
|
59
|
+
def has_attributes(*attributes)
|
60
|
+
opts = attributes.pop
|
61
|
+
attributes.each do |name|
|
62
|
+
path = opts[:datastream][:path] + opts[:datastream][:type].mappings[name]
|
63
|
+
path << FedoraLens::Lenses.single unless opts[:multiple]
|
64
|
+
attribute name, path
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Example
|
70
|
+
include FedoraLens
|
71
|
+
include FedoraLens::Lenses
|
72
|
+
extend Metadata
|
73
|
+
has_attributes :date_uploaded, datastream: descMetadata, multiple: true
|
74
|
+
has_attributes :title, datastream: descMetadata, multiple: true
|
75
|
+
# has_attributes :relative_path, datastream: properties, multiple: false
|
76
|
+
end
|
data/fedora/.gitkeep
ADDED
File without changes
|
data/fedora_lens.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fedora_lens/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fedora_lens"
|
8
|
+
spec.version = FedoraLens::VERSION
|
9
|
+
spec.authors = ["Justin Coyne", "Brian Maddy"]
|
10
|
+
spec.email = ["justin@curationexperts.com"]
|
11
|
+
spec.summary = %q{A client for Fedora Commons Repository (fcrepo) version 4}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "APACHE2"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "childprocess"
|
25
|
+
|
26
|
+
spec.add_dependency 'rdf-turtle', '~> 1.1.2'
|
27
|
+
spec.add_dependency 'activemodel', '>= 4.0.2', "< 5.0"
|
28
|
+
spec.add_dependency 'nokogiri', '~> 1.6.1'
|
29
|
+
spec.add_dependency 'ldp'
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
|
3
|
+
module FedoraLens
|
4
|
+
class Lens < ActiveSupport::HashWithIndifferentAccess
|
5
|
+
def get(source)
|
6
|
+
self[:get].call(source)
|
7
|
+
end
|
8
|
+
def put(source, value)
|
9
|
+
self[:put].call(source, value)
|
10
|
+
end
|
11
|
+
def create(value)
|
12
|
+
self[:create].call(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module FedoraLens
|
2
|
+
module LensTests
|
3
|
+
# See page 6 of the manual for the Harmony language for a description
|
4
|
+
# on how lenses work
|
5
|
+
# http://www.seas.upenn.edu/~harmony/manual.pdf
|
6
|
+
# @example testing a lens that converts xml to a dom and back
|
7
|
+
# test_lens(lens, Nokogiri::XML("<a/>"), Nokogiri::XML("<b/>") do |v|
|
8
|
+
# v.to_xml
|
9
|
+
# end
|
10
|
+
# @param [lens]
|
11
|
+
# the lens to test
|
12
|
+
# @param [value]
|
13
|
+
# the value to test with (when calling put)
|
14
|
+
# @param [source]
|
15
|
+
# the source document this lens operates on
|
16
|
+
# @yield [converter]
|
17
|
+
# a block that converts the value from the lens to something that can be
|
18
|
+
# compared with #== (defaults to the identity function)
|
19
|
+
# @yieldparam [value or source]
|
20
|
+
# a value that will be compared
|
21
|
+
def test_lens(lens, source, value, &block)
|
22
|
+
test_lens_get_put(lens, source, &block)
|
23
|
+
test_lens_put_get(lens, source, value, &block)
|
24
|
+
test_lens_create_get(lens, value, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_lens_get_put(lens, source)
|
28
|
+
it "is well-behaved (GetPut: put(source, get(source)) == source)" do
|
29
|
+
converted = lens.put(source, lens.get(source))
|
30
|
+
if block_given?
|
31
|
+
yield(converted).should eq yield(source)
|
32
|
+
else
|
33
|
+
converted.should eq source
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_lens_put_get(lens, source, value)
|
39
|
+
it "is well-behaved (PutGet: get(put(source, value)) == value)" do
|
40
|
+
converted = lens.get(lens.put(source, value))
|
41
|
+
if block_given?
|
42
|
+
yield(converted).should eq yield(value)
|
43
|
+
else
|
44
|
+
converted.should eq value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_lens_create_get(lens, value)
|
50
|
+
it "is well-behaved (CreateGet: get(create(value)) == value)" do
|
51
|
+
created = lens.get(lens.create(value))
|
52
|
+
if block_given?
|
53
|
+
yield(created).should eq yield(value)
|
54
|
+
else
|
55
|
+
created.should eq value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'fedora_lens/lens'
|
2
|
+
|
3
|
+
module FedoraLens
|
4
|
+
module Lenses
|
5
|
+
# We would like to use lenses like this: Lenses.at_css.get(...)
|
6
|
+
# Using a simple hash is gross because calls are like this: Lenses.at_css[:get].call(...)
|
7
|
+
# If we use a Module, we can't pass in parameters to build a more specific lens like
|
8
|
+
# in the case of the at_css lens.
|
9
|
+
# If we use a class, we need to call it like this: Lenses::AtCss.new('path').get(...)
|
10
|
+
# that's a lot of ".new" that just becomes line noise
|
11
|
+
# Classes don't seem to close over their environment as a function would (not sure why...)
|
12
|
+
# so we can create anonymous classes with functions
|
13
|
+
# Instead, we're just adding the helper functions to a simple hash.
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def single
|
17
|
+
Lens[
|
18
|
+
get: :first.to_proc,
|
19
|
+
put: lambda {|source, value| source[0] = value; source},
|
20
|
+
create: lambda {|value| [value]}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def literal_to_string
|
25
|
+
Lens[
|
26
|
+
get: :to_s.to_proc,
|
27
|
+
put: lambda do |source, value|
|
28
|
+
if source.is_a?(RDF::Literal)
|
29
|
+
RDF::Literal.new(value, language: source.language, datatype: source.datatype)
|
30
|
+
else
|
31
|
+
RDF::Literal.new(value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
def hash_update
|
38
|
+
Lens[
|
39
|
+
get: lambda {|hash| hash[key]},
|
40
|
+
put: lambda {|hash, pair| hash.merge(pair[0] => pair[1])}
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
def orm_to_hash(name_to_lens)
|
45
|
+
Lens[
|
46
|
+
get: lambda do |orm|
|
47
|
+
name_to_lens.reduce({}) do |hash, pair|
|
48
|
+
key, lens = pair
|
49
|
+
hash.merge(key => lens.get(orm))
|
50
|
+
end
|
51
|
+
end,
|
52
|
+
put: lambda do |orm, hash|
|
53
|
+
name_to_lens.each do |pair|
|
54
|
+
key, lens = pair
|
55
|
+
lens.put(orm, hash[key])
|
56
|
+
end
|
57
|
+
orm
|
58
|
+
end
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def as_dom
|
63
|
+
Lens[
|
64
|
+
# TODO figure out a memoizing strategy so we don't parse multiple times
|
65
|
+
get: lambda {|xml| Nokogiri::XML(xml)},
|
66
|
+
put: lambda {|xml, value| value.to_xml},
|
67
|
+
create: lambda {|value| value.to_xml}
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
71
|
+
def at_css(selector)
|
72
|
+
Lens[
|
73
|
+
get: lambda {|doc| doc.at_css(selector).content},
|
74
|
+
put: lambda {|doc, value|
|
75
|
+
doc.at_css(selector).content = value; doc},
|
76
|
+
# can't do a css create because we don't know the structure
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_predicate(predicate)
|
81
|
+
Lens[
|
82
|
+
get: lambda do |orm|
|
83
|
+
orm.value(predicate)
|
84
|
+
end,
|
85
|
+
put: lambda do |orm, values|
|
86
|
+
orm.graph.delete([orm.resource.subject_uri, predicate, nil])
|
87
|
+
(values || []).each do |value|
|
88
|
+
orm.graph.insert([orm.resource.subject_uri, predicate, value])
|
89
|
+
end
|
90
|
+
orm
|
91
|
+
end,
|
92
|
+
create: lambda do |values|
|
93
|
+
orm = Ldp::Orm.new(Ldp::Resource.new(nil, '', RDF::Graph.new))
|
94
|
+
values.each do |value|
|
95
|
+
orm.graph.insert([orm.resource.subject_uri, predicate, value])
|
96
|
+
end
|
97
|
+
orm
|
98
|
+
end
|
99
|
+
]
|
100
|
+
end
|
101
|
+
|
102
|
+
def load_model(klass)
|
103
|
+
Lens[
|
104
|
+
get: lambda do |id|
|
105
|
+
klass.find(id)
|
106
|
+
end,
|
107
|
+
put: lambda do |id, model|
|
108
|
+
model.save
|
109
|
+
id
|
110
|
+
end
|
111
|
+
]
|
112
|
+
end
|
113
|
+
|
114
|
+
def load_or_build_orm
|
115
|
+
Lens[
|
116
|
+
get: lambda do |uri|
|
117
|
+
if uri.present?
|
118
|
+
Ldp::Orm.new(Ldp::Resource.new(FedoraLens.connection, uri.to_s))
|
119
|
+
else
|
120
|
+
Ldp::Orm.new(Ldp::Resource.new(FedoraLens.connection, nil, RDF::Graph.new))
|
121
|
+
end
|
122
|
+
end,
|
123
|
+
put: lambda do |uri, orm|
|
124
|
+
if orm.resource.subject.present?
|
125
|
+
orm.save
|
126
|
+
else
|
127
|
+
orm.resource.create
|
128
|
+
end
|
129
|
+
orm.resource.subject_uri
|
130
|
+
end
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
def compose(outer, inner)
|
135
|
+
Lens[
|
136
|
+
get: lambda do |source|
|
137
|
+
inner.get(outer.get(source))
|
138
|
+
end,
|
139
|
+
put: lambda do |source, value|
|
140
|
+
outer.put(source, inner.put(outer.get(source), value))
|
141
|
+
end
|
142
|
+
]
|
143
|
+
end
|
144
|
+
|
145
|
+
def zip(first, second)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/fedora_lens.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'rdf'
|
2
|
+
require 'ldp'
|
3
|
+
require 'ldp_monkeypatch'
|
4
|
+
require 'rdf/turtle'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'active_model'
|
7
|
+
require 'active_support/concern'
|
8
|
+
require 'active_support/core_ext/object'
|
9
|
+
require 'active_support/core_ext/class/attribute'
|
10
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
11
|
+
require 'active_support/core_ext/hash'
|
12
|
+
require 'fedora_lens/errors'
|
13
|
+
|
14
|
+
module FedoraLens
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
HOST = "http://localhost:8983/fedora"
|
17
|
+
#HOST = "http://localhost:8080"
|
18
|
+
PATH = '/rest'
|
19
|
+
|
20
|
+
def self.connection
|
21
|
+
@@connection ||= Ldp::Client.new(HOST)
|
22
|
+
end
|
23
|
+
|
24
|
+
included do
|
25
|
+
extend ActiveModel::Naming
|
26
|
+
include ActiveModel::Validations
|
27
|
+
include ActiveModel::Conversion
|
28
|
+
|
29
|
+
class_attribute :attributes_as_lenses
|
30
|
+
self.attributes_as_lenses = {}.with_indifferent_access
|
31
|
+
|
32
|
+
attr_reader :attributes
|
33
|
+
attr_reader :orm
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(subject_or_data = {}, data = nil)
|
37
|
+
init_core(subject_or_data, data)
|
38
|
+
end
|
39
|
+
|
40
|
+
def persisted?() false end
|
41
|
+
|
42
|
+
def errors
|
43
|
+
obj = Object.new
|
44
|
+
def obj.[](key) [] end
|
45
|
+
def obj.full_messages() [] end
|
46
|
+
obj
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_attribute_for_validation(key)
|
50
|
+
@attributes[key]
|
51
|
+
end
|
52
|
+
|
53
|
+
def reload
|
54
|
+
@orm = @orm.reload
|
55
|
+
@attributes = get_attributes_from_orm(@orm)
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete
|
59
|
+
@orm.resource.delete
|
60
|
+
end
|
61
|
+
|
62
|
+
def save
|
63
|
+
@orm = self.class.orm_to_hash.put(@orm, @attributes)
|
64
|
+
new_record? ? create_record : update_record
|
65
|
+
end
|
66
|
+
|
67
|
+
def save!
|
68
|
+
save || raise(RecordNotSaved)
|
69
|
+
end
|
70
|
+
|
71
|
+
def new_record?
|
72
|
+
@new_record
|
73
|
+
end
|
74
|
+
|
75
|
+
def uri
|
76
|
+
@orm.try(:resource).try(:subject_uri).try(:to_s)
|
77
|
+
end
|
78
|
+
|
79
|
+
def id
|
80
|
+
URI.parse(uri).to_s.sub(HOST + PATH, '') if uri.present?
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
# This allows you to overide the initializer, but still use this behavior
|
85
|
+
def init_core(subject_or_data = {}, data = nil)
|
86
|
+
@new_record = true
|
87
|
+
case subject_or_data
|
88
|
+
when Ldp::Resource
|
89
|
+
@orm = Ldp::Orm.new(subject_or_data)
|
90
|
+
@attributes = get_attributes_from_orm(@orm)
|
91
|
+
when NilClass, Hash
|
92
|
+
data = subject_or_data || {}
|
93
|
+
@orm = Ldp::Orm.new(Ldp::Resource.new(FedoraLens.connection, nil, RDF::Graph.new))
|
94
|
+
@attributes = data.with_indifferent_access
|
95
|
+
when String
|
96
|
+
data ||= {}
|
97
|
+
@orm = Ldp::Orm.new(Ldp::Resource.new(FedoraLens.connection, subject_or_data, RDF::Graph.new))
|
98
|
+
@attributes = data.with_indifferent_access
|
99
|
+
else
|
100
|
+
raise ArgumentError, "#{data.class} is not acceptable"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def create_record
|
105
|
+
orm.resource.create
|
106
|
+
@new_record = false
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def update_record
|
111
|
+
# Fedora errors out when you try to set the rdf:type
|
112
|
+
# see https://github.com/cbeer/ldp/issues/2
|
113
|
+
orm.graph.delete([@orm.resource.subject_uri,
|
114
|
+
RDF::URI.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
|
115
|
+
nil])
|
116
|
+
orm.save
|
117
|
+
orm.last_response.success?
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def get_attributes_from_orm(orm)
|
124
|
+
self.class.orm_to_hash.get(orm).with_indifferent_access
|
125
|
+
end
|
126
|
+
|
127
|
+
module ClassMethods
|
128
|
+
def find(id)
|
129
|
+
resource = Ldp::Resource.new(FedoraLens.connection, id_to_uri(id))
|
130
|
+
self.new(resource)
|
131
|
+
end
|
132
|
+
|
133
|
+
def id_to_uri(id)
|
134
|
+
"#{HOST}#{PATH}#{id}"
|
135
|
+
end
|
136
|
+
|
137
|
+
def attribute(name, path, options={})
|
138
|
+
raise AttributeNotSupportedException if name.to_sym == :id
|
139
|
+
attributes_as_lenses[name] = path.map{|s| coerce_to_lens(s)}
|
140
|
+
define_method name do
|
141
|
+
@attributes[name]
|
142
|
+
end
|
143
|
+
define_method "#{name}=" do |value|
|
144
|
+
@attributes[name] = value
|
145
|
+
end
|
146
|
+
orm_to_hash = nil # force us to rebuild the aggregate_lens in case it was already built.
|
147
|
+
end
|
148
|
+
|
149
|
+
def create(data)
|
150
|
+
model = self.new(data)
|
151
|
+
model.save
|
152
|
+
model
|
153
|
+
end
|
154
|
+
|
155
|
+
def orm_to_hash
|
156
|
+
if @orm_to_hash.nil?
|
157
|
+
aggregate_lens = attributes_as_lenses.reduce({}) do |acc, pair|
|
158
|
+
name, path = pair
|
159
|
+
lens = path.reduce {|outer, inner| Lenses.compose(outer, inner)}
|
160
|
+
acc.merge(name => lens)
|
161
|
+
end
|
162
|
+
@orm_to_hash = Lenses.orm_to_hash(aggregate_lens)
|
163
|
+
end
|
164
|
+
@orm_to_hash
|
165
|
+
end
|
166
|
+
|
167
|
+
def coerce_to_lens(path_segment)
|
168
|
+
if path_segment.is_a? RDF::URI
|
169
|
+
Lenses.get_predicate(path_segment)
|
170
|
+
else
|
171
|
+
path_segment
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# def has_one(name, scope = nil, options = {})
|
176
|
+
# ActiveRecord::Associations::Builder::HasOne.build(self, name, scope, options)
|
177
|
+
# end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
require 'fedora_lens/lenses'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'ldp'
|
2
|
+
module Ldp
|
3
|
+
|
4
|
+
class Resource
|
5
|
+
def create
|
6
|
+
# create seems to not be working in ldp, but it's not entirely clear how it should work
|
7
|
+
# for example, :new? calls :get, which will raise an error when an object doesn't exist,
|
8
|
+
# this means it is impossible to create anything.
|
9
|
+
# raise "" if new?
|
10
|
+
# puts "MONKEY patch create #{client.inspect}"
|
11
|
+
# puts "Graph #{graph.dump(:ttl)}"
|
12
|
+
resp = client.post '/fedora/rest', graph.dump(:ttl) do |req|
|
13
|
+
# req.headers['Slug'] = subject
|
14
|
+
end
|
15
|
+
|
16
|
+
# puts "Heards #{resp.headers.inspect}"
|
17
|
+
@subject = resp.headers['Location']
|
18
|
+
# puts "Loc #{@subject.inspect}"
|
19
|
+
@subject_uri = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/test_class.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fedora_lens'
|
2
|
+
class TestClass
|
3
|
+
include FedoraLens
|
4
|
+
include FedoraLens::Lenses
|
5
|
+
|
6
|
+
def self.custom_lens(type)
|
7
|
+
Lens[
|
8
|
+
get: lambda do |doc|
|
9
|
+
if node = doc.at_css("relationship[type=#{type}]")
|
10
|
+
node.content
|
11
|
+
else
|
12
|
+
""
|
13
|
+
end
|
14
|
+
end,
|
15
|
+
put: lambda do |doc, value|
|
16
|
+
# TODO: create missing nodes
|
17
|
+
# doc.at_css(selector).content = value; doc
|
18
|
+
doc << Nokogiri::XML::Node.new("relationships", doc) if doc.root.nil?
|
19
|
+
root = doc.root
|
20
|
+
relationship = root.at_css("relationship[type=#{type}]")
|
21
|
+
if relationship.nil?
|
22
|
+
relationship = Nokogiri::XML::Node.new("relationship", doc)
|
23
|
+
relationship.set_attribute("type", type)
|
24
|
+
root << relationship
|
25
|
+
end
|
26
|
+
relationship.content = value
|
27
|
+
doc
|
28
|
+
end,
|
29
|
+
create: lambda do |value|
|
30
|
+
Nokogiri::XML("<relationships>
|
31
|
+
<relationship type=\"#{type}\">#{value}</relationship>
|
32
|
+
</relationships>")
|
33
|
+
end
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
attribute :title, [RDF::DC11.title, Lenses.single, Lenses.literal_to_string]
|
38
|
+
attribute :mixinTypes, [
|
39
|
+
RDF::URI.new("http://fedora.info/definitions/v4/repository#mixinTypes")]
|
40
|
+
attribute :primaryType, [
|
41
|
+
RDF::URI.new("http://fedora.info/definitions/v4/repository#primaryType"),
|
42
|
+
Lenses.single,
|
43
|
+
Lenses.literal_to_string]
|
44
|
+
attribute :primary_id, [
|
45
|
+
RDF::DC11.relation,
|
46
|
+
Lenses.single,
|
47
|
+
Lenses.literal_to_string,
|
48
|
+
Lenses.as_dom,
|
49
|
+
# Lenses.at_css("relationship[type=primary]")]
|
50
|
+
custom_lens("primary")]
|
51
|
+
attribute :secondary, [
|
52
|
+
RDF::DC11.relation,
|
53
|
+
Lenses.single,
|
54
|
+
Lenses.literal_to_string,
|
55
|
+
Lenses.as_dom,
|
56
|
+
custom_lens("secondary"),
|
57
|
+
# Lenses.at_css("relationship[type=secondary]"),
|
58
|
+
# Lenses.load_model(TestRelated)
|
59
|
+
]
|
60
|
+
# def self.generated_feature_methods
|
61
|
+
# end
|
62
|
+
# has_one :primary
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fedora_lens/lens_tests'
|
3
|
+
|
4
|
+
module FedoraLens
|
5
|
+
describe Lenses do
|
6
|
+
extend LensTests
|
7
|
+
|
8
|
+
describe ".single" do
|
9
|
+
it "gets the first item" do
|
10
|
+
Lenses.single.get([:first, :second]).should eq :first
|
11
|
+
end
|
12
|
+
it "sets the first item" do
|
13
|
+
Lenses.single.put([:first, :second], :changed).should eq [:changed, :second]
|
14
|
+
end
|
15
|
+
it "creates an item in an array" do
|
16
|
+
Lenses.single.create(:value).should eq [:value]
|
17
|
+
end
|
18
|
+
test_lens Lenses.single, [], :foo
|
19
|
+
test_lens Lenses.single, [:one], :foo
|
20
|
+
test_lens Lenses.single, [:one, :two], :foo
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".as_dom" do
|
24
|
+
it "converts xml to a Nokogiri::XML::Document" do
|
25
|
+
xml = "<foo><bar>content</bar></foo>"
|
26
|
+
Lenses.as_dom.get(xml).to_xml.should eq Nokogiri::XML(xml).to_xml
|
27
|
+
end
|
28
|
+
it "converts a modified Nokogiri::XML::Document back to xml" do
|
29
|
+
xml = "<foo><bar>content</bar></foo>"
|
30
|
+
modified = Nokogiri::XML("<foo><bar>changed</bar></foo>")
|
31
|
+
Lenses.as_dom.put(xml, modified.dup).should eq modified.to_xml
|
32
|
+
end
|
33
|
+
it "creates a new string of xml" do
|
34
|
+
value = Nokogiri::XML("<foo><bar>created</bar></foo>")
|
35
|
+
Lenses.as_dom.create(value).should eq value.to_xml
|
36
|
+
end
|
37
|
+
test_lens(Lenses.as_dom,
|
38
|
+
Nokogiri::XML("<foo><bar>content</bar></foo>").to_xml,
|
39
|
+
Nokogiri::XML("<foo><bar>new content</bar></foo>")){|v| v.to_s}
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".at_css" do
|
43
|
+
it "gets the content at the css selector" do
|
44
|
+
dom = Nokogiri::XML("<foo><bar>content</bar></foo>")
|
45
|
+
Lenses.at_css('foo bar').get(dom).should eq 'content'
|
46
|
+
end
|
47
|
+
it "sets the first item" do
|
48
|
+
dom = Nokogiri::XML("<foo><bar>content</bar></foo>")
|
49
|
+
expected = Nokogiri::XML("<foo><bar>changed</bar></foo>")
|
50
|
+
Lenses.at_css('foo bar').put(dom, :changed).to_xml.should eq expected.to_xml
|
51
|
+
end
|
52
|
+
test_lens_get_put(Lenses.at_css("foo bar"), Nokogiri::XML("<foo><bar>content</bar></foo>"))
|
53
|
+
test_lens_put_get(Lenses.at_css("foo bar"),
|
54
|
+
Nokogiri::XML("<foo><bar>content</bar></foo>"),
|
55
|
+
"new content")
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ".get_predicate" do
|
59
|
+
let(:orm) do
|
60
|
+
graph = RDF::Graph.new
|
61
|
+
orm = Ldp::Orm.new(Ldp::Resource.new(nil, '', graph))
|
62
|
+
orm.graph.insert([orm.resource.subject_uri, RDF::DC11.title, "title"])
|
63
|
+
orm
|
64
|
+
end
|
65
|
+
it "converts an Ldp::Orm to the value of the specified predicate" do
|
66
|
+
Lenses.get_predicate(RDF::DC11.title).get(orm).first.should eq RDF::Literal.new("title")
|
67
|
+
end
|
68
|
+
it "sets the value of an Ldp::Orm for the specified predicate" do
|
69
|
+
Lenses.get_predicate(RDF::DC11.title).put(orm, [RDF::Literal.new("new")]).value(RDF::DC11.title).first.should eq RDF::Literal.new("new")
|
70
|
+
end
|
71
|
+
it "creates a new Ldp::Orm with the value for a specified predicate" do
|
72
|
+
converted = Lenses.get_predicate(RDF::DC11.title).create([RDF::Literal.new("title")])
|
73
|
+
converted.graph.dump(:ttl).should eq orm.graph.dump(:ttl)
|
74
|
+
end
|
75
|
+
graph = RDF::Graph.new
|
76
|
+
orm = Ldp::Orm.new(Ldp::Resource.new(nil, '', graph))
|
77
|
+
orm.graph.insert([orm.resource.subject_uri, RDF::DC11.title, "title"])
|
78
|
+
test_lens(Lenses.get_predicate(RDF::DC11.title), orm, [RDF::Literal.new("new title")]) do |v|
|
79
|
+
if v.is_a? Ldp::Orm
|
80
|
+
v.value(RDF::DC11.title)
|
81
|
+
else
|
82
|
+
v
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FedoraLens do
|
4
|
+
include ActiveModel::Lint::Tests
|
5
|
+
|
6
|
+
class TestClass
|
7
|
+
include FedoraLens
|
8
|
+
attribute :title, [RDF::DC11.title, Lenses.single, Lenses.literal_to_string]
|
9
|
+
# attribute :xml_title, [RDF::DC11.title, Lenses.single]
|
10
|
+
end
|
11
|
+
|
12
|
+
# for ActiveModel::Lint::Tests
|
13
|
+
def setup
|
14
|
+
@model = TestClass.new
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { TestClass.new }
|
18
|
+
|
19
|
+
describe ".find" do
|
20
|
+
context "when the object doesn't exist" do
|
21
|
+
it "should raise an error" do
|
22
|
+
expect{ TestClass.find('bahvejlavawwv') }.to raise_error Ldp::NotFound
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the object exists" do
|
27
|
+
let(:existing) { TestClass.create(title: "created resource") }
|
28
|
+
subject { TestClass.find(existing.id) }
|
29
|
+
it { should be_kind_of TestClass }
|
30
|
+
its(:id) { should eq existing.id }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".delete" do
|
35
|
+
subject { TestClass.create(title: "created resource") }
|
36
|
+
|
37
|
+
it "should be deleted" do
|
38
|
+
subject.delete
|
39
|
+
expect{ TestClass.find(subject.id) }.to raise_error Ldp::NotFound
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".create" do
|
44
|
+
subject { TestClass.create(attributes) }
|
45
|
+
context "with a hash" do
|
46
|
+
let(:attributes) { { title: "created resource" } }
|
47
|
+
it "creates a resource" do
|
48
|
+
expect(TestClass.find(subject.id).title).to eq "created resource"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
context "with nil" do
|
52
|
+
let(:attributes) { nil }
|
53
|
+
it "creates a resource" do
|
54
|
+
expect(TestClass.find(subject.id)).to be_kind_of TestClass
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#id" do
|
60
|
+
it "should not have 'fedora' in the id" do
|
61
|
+
m = TestClass.new('http://localhost:8983/fedora/rest/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52')
|
62
|
+
expect(m.id).to eq '/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
describe ".save" do
|
68
|
+
it "saves a new resource" do
|
69
|
+
m = TestClass.new(title: "created resource")
|
70
|
+
m.save
|
71
|
+
TestClass.find(m.id).title.should eq "created resource"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "saves an updated resource" do
|
75
|
+
m = TestClass.create(title: "created resource")
|
76
|
+
m.reload
|
77
|
+
m.title = "changed title"
|
78
|
+
m.save
|
79
|
+
TestClass.find(m.id).title.should eq "changed title"
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with a supplied id" do
|
83
|
+
subject { TestClass.new(TestClass.id_to_uri('foobar')) }
|
84
|
+
|
85
|
+
it "saves with that id" do
|
86
|
+
expect(subject.new_record?).to be_true
|
87
|
+
expect(subject.save).to be_true
|
88
|
+
expect(subject.new_record?).to be_false
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe ".attribute" do
|
96
|
+
it "makes a setter/getter" do
|
97
|
+
subject.title = "foo"
|
98
|
+
subject.title.should eq "foo"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "loads from rdf" do
|
102
|
+
end
|
103
|
+
|
104
|
+
it "mixes rdf and xml" do
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require "bundler/setup"
|
3
|
+
require 'fedora_lens'
|
4
|
+
require 'fedora_lens/lenses'
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.filter_run :focus
|
10
|
+
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fedora_lens
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Coyne
|
8
|
+
- Brian Maddy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.5'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.5'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: childprocess
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rdf-turtle
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.1.2
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 1.1.2
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: activemodel
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 4.0.2
|
91
|
+
- - <
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '5.0'
|
94
|
+
type: :runtime
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 4.0.2
|
101
|
+
- - <
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '5.0'
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: nokogiri
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.6.1
|
111
|
+
type: :runtime
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.6.1
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: ldp
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
type: :runtime
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
description: ''
|
133
|
+
email:
|
134
|
+
- justin@curationexperts.com
|
135
|
+
executables: []
|
136
|
+
extensions: []
|
137
|
+
extra_rdoc_files: []
|
138
|
+
files:
|
139
|
+
- .gitignore
|
140
|
+
- .rspec
|
141
|
+
- .ruby-version
|
142
|
+
- .travis.yml
|
143
|
+
- Gemfile
|
144
|
+
- README.md
|
145
|
+
- Rakefile
|
146
|
+
- config/jetty.yml
|
147
|
+
- demo.rb
|
148
|
+
- fedora/.gitkeep
|
149
|
+
- fedora_lens.gemspec
|
150
|
+
- lib/fedora_lens.rb
|
151
|
+
- lib/fedora_lens/errors.rb
|
152
|
+
- lib/fedora_lens/lens.rb
|
153
|
+
- lib/fedora_lens/lens_tests.rb
|
154
|
+
- lib/fedora_lens/lenses.rb
|
155
|
+
- lib/fedora_lens/version.rb
|
156
|
+
- lib/ldp_monkeypatch.rb
|
157
|
+
- lib/test_class.rb
|
158
|
+
- spec/fedora_lens/lenses_spec.rb
|
159
|
+
- spec/fedora_lens_spec.rb
|
160
|
+
- spec/spec_helper.rb
|
161
|
+
homepage: ''
|
162
|
+
licenses:
|
163
|
+
- APACHE2
|
164
|
+
metadata: {}
|
165
|
+
post_install_message:
|
166
|
+
rdoc_options: []
|
167
|
+
require_paths:
|
168
|
+
- lib
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - '>='
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
requirements: []
|
180
|
+
rubyforge_project:
|
181
|
+
rubygems_version: 2.1.11
|
182
|
+
signing_key:
|
183
|
+
specification_version: 4
|
184
|
+
summary: A client for Fedora Commons Repository (fcrepo) version 4
|
185
|
+
test_files:
|
186
|
+
- spec/fedora_lens/lenses_spec.rb
|
187
|
+
- spec/fedora_lens_spec.rb
|
188
|
+
- spec/spec_helper.rb
|
189
|
+
has_rdoc:
|