active-triples 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1dcbe5917c46ab351078d1c6e7b2be54d66c68f
4
+ data.tar.gz: 5cc8dfc6dfbba4a833566f568d395a15ba79c535
5
+ SHA512:
6
+ metadata.gz: 17d3134eb50d437947dada9a3eadd4b298968c2fef571e25796de38f4b6de48b3eef9935fcfd9c0a5cd9089570ddd4f4fdcd40a9e1a499d5521026e1d8de020b
7
+ data.tar.gz: 6beee86d363f0791be42dbd5507a6dad99fa3e7ceb2beedacd39d704ee63ade58dba85fec512d0f5d25fdbf60088844b7aaeb9b3917a70ef697d020193782c9f
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ Gemfile.lock
5
+ tmp/*
6
+ .sass-cache
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ anguage: ruby
2
+ bundler_args: --without debug
3
+ script: "bundle exec rspec spec"
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - 2.1.1
9
+ - jruby-19mode
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: jruby-19mode
data/AUTHORS ADDED
@@ -0,0 +1,2 @@
1
+ Tom Johnson (thomas.johnson@oregonstate.edu)
2
+ Trey Terrell
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ ActiveTriples
2
+ ==============
3
+
4
+ [![Build Status](https://travis-ci.org/no-reply/ActiveTriples.png?branch=master)](https://travis-ci.org/no-reply/ActiveTriples)
5
+
6
+ Modeling RDF graphs in Ruby.
7
+
8
+ How to Use
9
+ -----------
10
+
11
+ ```ruby
12
+ class Thing < ActiveTriples::Resource
13
+ configure :type => RDF::OWL.Thing, :base_uri => 'http://example.org/things#'
14
+ property :title, :predicate => RDF::DC.title
15
+ property :description, :predicate => RDF::DC.description
16
+ property :creator, :predicate => RDF::DC.creator, :class_name => 'Person'
17
+ end
18
+
19
+ obj = Thing.new('123')
20
+ obj.title = 'Resource'
21
+ obj.description = 'A resource in an RDF graph.'
22
+
23
+ obj.dump :ntriples
24
+ # => "<http://example.org/things#123> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .\n<http://example.org/things#123> <http://purl.org/dc/terms/title> \"Resource\" .\n<http://example.org/things#123> <http://purl.org/dc/terms/description> \"A resource in an RDF graph.\" .\n"
25
+
26
+ class Person < ActiveTriples::Resource
27
+ configure :type => RDF::FOAF.Person, :base_uri => 'http://example.org/people#'
28
+ property :name, :predicate => RDF::FOAF.name
29
+ end
30
+
31
+ obj.creator = Person.new
32
+ obj.creator
33
+ # => [#<Person:0x3fbe84ac9234(default)>]
34
+
35
+ obj.creator.first.name = 'Herman Melville'
36
+ obj.dump :ntriples
37
+ # => "<http://example.org/things#123> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .\n<http://example.org/things#123> <http://purl.org/dc/terms/title> \"Resource\" .\n<http://example.org/things#123> <http://purl.org/dc/terms/description> \"A resource in an RDF graph.\" .\n<http://example.org/things#123> <http://purl.org/dc/terms/creator> _:g70087502237940 .\n_:g70087502237940 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .\n"
38
+ ```
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "active_triples/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "active-triples"
7
+ s.version = ActiveTriples::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Tom Johnson", "Trey Terrell"]
10
+ s.homepage = 'https://github.com/no-reply/ActiveTriples'
11
+ s.email = 'thomas.johnson@oregonstate.edu'
12
+ s.summary = %q{RDF graphs in ActiveModel wrappers.}
13
+ s.description = %q{ActiveTriples provides tools for modeling RDF as discrete resources.}
14
+ s.license = "Public Domain"
15
+ s.required_ruby_version = '>= 1.9.3'
16
+
17
+ s.add_dependency('rdf', '~> 1.1')
18
+ s.add_dependency('linkeddata', '~> 1.1')
19
+ s.add_dependency('activemodel')
20
+ s.add_dependency('deprecation', '~> 0.1')
21
+ s.add_dependency('activesupport')
22
+
23
+ s.add_development_dependency('rdoc')
24
+ s.add_development_dependency('rspec')
25
+ s.add_development_dependency('webmock')
26
+ s.add_development_dependency('nokogiri')
27
+
28
+ s.files = `git ls-files`.split("\n")
29
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
30
+
31
+ s.extra_rdoc_files = [
32
+ "LICENSE",
33
+ "README.md"
34
+ ]
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'rdf'
2
+ require 'active_triples/version'
3
+
4
+ module ActiveTriples
5
+ autoload :Resource, 'active_triples/resource'
6
+ autoload :List, 'active_triples/list'
7
+ autoload :Term, 'active_triples/term'
8
+ autoload :Indexing, 'active_triples/indexing'
9
+ autoload :Configurable, 'active_triples/configurable'
10
+ autoload :Properties, 'active_triples/properties'
11
+ autoload :Repositories, 'active_triples/repositories'
12
+ autoload :NodeConfig, 'active_triples/node_config'
13
+ autoload :NestedAttributes, 'active_triples/nested_attributes'
14
+
15
+ def self.class_from_string(class_name, container_class=Kernel)
16
+ container_class = container_class.name if container_class.is_a? Module
17
+ container_parts = container_class.split('::')
18
+ (container_parts + class_name.split('::')).flatten.inject(Kernel) do |mod, class_name|
19
+ if mod == Kernel
20
+ Object.const_get(class_name)
21
+ elsif mod.const_defined? class_name.to_sym
22
+ mod.const_get(class_name)
23
+ else
24
+ container_parts.pop
25
+ class_from_string(class_name, container_parts.join('::'))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,61 @@
1
+ require 'deprecation'
2
+
3
+ module ActiveTriples
4
+ ##
5
+ # Module to include configurable class-wide properties common to
6
+ # Resource and RDFDatastream. It does its work at the class level,
7
+ # and is meant to be extended.
8
+ #
9
+ # Define properties at the class level with:
10
+ #
11
+ # configure base_uri: "http://oregondigital.org/resource/", repository: :parent
12
+ # Available properties are base_uri, rdf_label, type, and repository
13
+ module Configurable
14
+ extend Deprecation
15
+
16
+ def base_uri
17
+ nil
18
+ end
19
+
20
+ def rdf_label
21
+ nil
22
+ end
23
+
24
+ def type
25
+ nil
26
+ end
27
+
28
+ def rdf_type(value)
29
+ Deprecation.warn Configurable, "rdf_type is deprecated and will be removed in active-fedora 8.0.0. Use configure type: instead.", caller
30
+ configure type: value
31
+ end
32
+
33
+ def repository
34
+ :parent
35
+ end
36
+
37
+ # API method for configuring class properties an RDF Resource may need.
38
+ # This is an alternative to overriding the methods extended with this module.
39
+ def configure(options = {})
40
+ {
41
+ base_uri: options[:base_uri],
42
+ rdf_label: options[:rdf_label],
43
+ type: options[:type],
44
+ repository: options[:repository]
45
+ }.each do |name, value|
46
+ if value
47
+ value = self.send("transform_#{name}", value) if self.respond_to?("transform_#{name}")
48
+ define_singleton_method(name) do
49
+ value
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def transform_type(value)
56
+ RDF::URI.new(value).tap do |value|
57
+ Resource.type_registry[value] = self
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,76 @@
1
+ module ActiveFedora
2
+ module Rdf
3
+ module Indexing
4
+ extend Deprecation
5
+ extend ActiveSupport::Concern
6
+
7
+ # In active_fedora 8, we can get the prefix part from Datastream.prefix
8
+ def apply_prefix(name)
9
+ "#{dsid.underscore}__#{name}"
10
+ end
11
+
12
+ def prefix(name)
13
+ Deprecation.warn Indexing, "prefix is deprecated. Use apply_prefix instead. In active-fedora 8, the prefix method will just return the prefix to be applied, and will not do the applying. This will enable conformity between OmDatastream and RdfDatastream"
14
+ apply_prefix(name)
15
+ end
16
+
17
+ def to_solr(solr_doc = Hash.new) # :nodoc:
18
+ fields.each do |field_key, field_info|
19
+ values = resource.get_values(field_key)
20
+ Array(values).each do |val|
21
+ if val.kind_of? RDF::URI
22
+ val = val.to_s
23
+ elsif val.kind_of? Rdf::Resource
24
+ val = val.solrize
25
+ end
26
+ self.class.create_and_insert_terms(apply_prefix(field_key), val, field_info[:behaviors], solr_doc)
27
+ end
28
+ end
29
+ solr_doc
30
+ end
31
+
32
+ # Gives the primary solr name for a column. If there is more than one indexer on the field definition, it gives the first
33
+ def primary_solr_name(field)
34
+ config = self.class.config_for_term_or_uri(field)
35
+ return nil unless config # punt on index names for deep nodes!
36
+ if behaviors = config.behaviors
37
+ behaviors.each do |behavior|
38
+ result = ActiveFedora::SolrService.solr_name(apply_prefix(field), behavior, type: config.type)
39
+ return result if Solrizer::DefaultDescriptors.send(behavior).evaluate_suffix(:text).stored?
40
+ end
41
+ raise RuntimeError "no stored fields were found"
42
+ end
43
+ end
44
+
45
+ module ClassMethods
46
+ def prefix(dsid, name)
47
+ Deprecation.warn Indexing, "prefix is deprecated and will be removed in active-fedora 8.0.0.", caller
48
+ "#{dsid.underscore}__#{name}".to_sym
49
+ end
50
+
51
+ # Gives the datatype for a column.
52
+ def type(field)
53
+ config_for_term_or_uri(field).type
54
+ end
55
+ end
56
+
57
+ private
58
+ # returns a Hash, e.g.: {field => {:values => [], :type => :something, :behaviors => []}, ...}
59
+ def fields
60
+ field_map = {}.with_indifferent_access
61
+
62
+ self.class.properties.each do |name, config|
63
+ type = config[:type]
64
+ behaviors = config[:behaviors]
65
+ next unless type and behaviors
66
+ next if config[:class_name] && config[:class_name] < ActiveFedora::Base
67
+ resource.query(:subject => rdf_subject, :predicate => config[:predicate]).each_statement do |statement|
68
+ field_map[name] ||= {:values => [], :type => type, :behaviors => behaviors}
69
+ field_map[name][:values] << statement.object.to_s
70
+ end
71
+ end
72
+ field_map
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,155 @@
1
+ module ActiveTriples
2
+ ##
3
+ # An implementation of RDF::List intregrated with ActiveTriples.
4
+ #
5
+ # A thoughtful reflection period is encouraged before using the
6
+ # rdf:List concept in your data. The community may pursue other
7
+ # options for ordered sets.
8
+ class List < RDF::List
9
+ include ActiveTriples::NestedAttributes
10
+ extend Configurable
11
+ extend Properties
12
+
13
+ delegate :rdf_subject, :mark_for_destruction, :marked_for_destruction?, :set_value, :get_values, :parent, :dump, :attributes=, to: :resource
14
+ alias_method :to_ary, :to_a
15
+
16
+ class << self
17
+ def from_uri(uri, vals)
18
+ list = ListResource.from_uri(uri, vals)
19
+ self.new(list.rdf_subject, list)
20
+ end
21
+ end
22
+
23
+ def resource
24
+ graph
25
+ end
26
+
27
+ def initialize(*args)
28
+ super
29
+ parent = graph.parent if graph.respond_to? :parent
30
+ @graph = ListResource.new(subject) << graph unless graph.kind_of? Resource
31
+ graph << parent if parent
32
+ graph.list = self
33
+ graph.singleton_class.properties = self.class.properties
34
+ graph.singleton_class.properties.keys.each do |property|
35
+ graph.singleton_class.send(:register_property, property)
36
+ end
37
+ graph.insert RDF::Statement.new(subject, RDF.type, RDF.List)
38
+ graph.reload
39
+ end
40
+
41
+ def []=(idx, value)
42
+ raise IndexError "index #{idx} too small for array: minimum 0" if idx < 0
43
+
44
+ if idx >= length
45
+ (idx - length).times do
46
+ self << RDF::OWL.Nothing
47
+ end
48
+ return self << value
49
+ end
50
+ each_subject.with_index do |v, i|
51
+ next unless i == idx
52
+ resource.set_value(v, RDF.first, value)
53
+ end
54
+ end
55
+
56
+ ##
57
+ # Override to return AF::Rdf::Resources as values, where
58
+ # appropriate.
59
+ def each(&block)
60
+ return super unless block_given?
61
+
62
+ super do |value|
63
+ block.call(node_from_value(value))
64
+ end
65
+ end
66
+
67
+ ##
68
+ # Do these like #each.
69
+ def first
70
+ node_from_value(super)
71
+ end
72
+
73
+ def shift
74
+ node_from_value(super)
75
+ end
76
+
77
+ ##
78
+ # Find an AF::Rdf::Resource from the value returned by RDF::List
79
+ def node_from_value(value)
80
+ if value.kind_of? RDF::Resource
81
+ type_uri = resource.query([value, RDF.type, nil]).to_a.first.try(:object)
82
+ klass = ActiveTriples::Resource.type_registry[type_uri]
83
+ klass ||= Resource
84
+ return klass.from_uri(value,resource)
85
+ end
86
+ value
87
+ end
88
+
89
+ ##
90
+ # This class is the graph/Resource that backs the List and
91
+ # supplies integration with the rest of ActiveTriples
92
+ class ListResource < Resource
93
+ attr_reader :list
94
+
95
+ def list=(list)
96
+ @list ||= list
97
+ end
98
+
99
+ def attributes=(values)
100
+ raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.kind_of? Hash
101
+ values.with_indifferent_access.each do |key, value|
102
+ if self.singleton_class.properties.keys.map{ |k| "#{k}_attributes"}.include?(key)
103
+ klass = properties[key[0..-12]]['class_name']
104
+ klass = ActiveTriples.class_from_string(klass, final_parent.class) if klass.is_a? String
105
+ value.is_a?(Hash) ? attributes_hash_to_list(values[key], klass) : attributes_to_list(value, klass)
106
+ values.delete key
107
+ end
108
+ end
109
+ persist!
110
+ super
111
+ end
112
+
113
+ private
114
+ def attributes_to_list(value, klass)
115
+ value.each do |entry|
116
+ item = klass.new()
117
+ item.attributes = entry
118
+ list << item
119
+ end
120
+ end
121
+
122
+ def attributes_hash_to_list(value, klass)
123
+ value.each do |counter, attr|
124
+ item = klass.new()
125
+ item.attributes = attr if attr
126
+ list[counter.to_i] = item
127
+ end
128
+ end
129
+ end
130
+
131
+ ##
132
+ # Monkey patch to allow lists to have subject URIs.
133
+ # Overrides RDF::List to prevent URI subjects
134
+ # from being replaced with nodes.
135
+ #
136
+ # @NOTE Lists built this way will return false for #valid?
137
+ def <<(value)
138
+ value = case value
139
+ when nil then RDF.nil
140
+ when RDF::Value then value
141
+ when Array then RDF::List.new(nil, graph, value)
142
+ else value
143
+ end
144
+
145
+ if empty?
146
+ resource.set_value(RDF.first, value)
147
+ resource.insert([subject, RDF.rest, RDF.nil])
148
+ resource << value if value.kind_of? Resource
149
+ return self
150
+ end
151
+ super
152
+ resource << value if value.kind_of? Resource
153
+ end
154
+ end
155
+ end