Module: TaliaCore::ActiveSourceParts::ClassMethods
- Included in:
- TaliaCore::ActiveSource
- Defined in:
- lib/talia_core/active_source_parts/class_methods.rb
Overview
Class methods for ActiveSource:
-
Property definitions for source classes (singular_property, multi_property, manual_property)
-
Logic for the creation of new sources, and things like exists?
-
“Import” methods for the class: create_from_xml, create_multi_from
-
autofill_uri logic
-
Various utility method
Instance Method Summary collapse
-
#additional_rdf_types ⇒ Object
Accessor for additional rdf types that will automatically be added to each object of that Source class.
-
#create_from_xml(xml, options = {}) ⇒ Object
Create sources from XML.
-
#create_multi_from(sources, options = {}) ⇒ Object
Creates multiple sources from the given array of attribute hashes.
-
#create_source(args) ⇒ Object
Retrieves a new source with the given type.
-
#db_attr?(attribute) ⇒ Boolean
Returns true if the given attribute is one that is stored in the database.
- #defined_property?(prop_name) ⇒ Boolean
-
#exists?(value) ⇒ Boolean
This method is slightly expanded to allow passing uris and uri objects as an “id”.
-
#expand_uri(uri) ⇒ Object
Tries to expand a generic URI value that is either given as a full URL or a namespace:name value.
-
#new(*args) ⇒ Object
New method for ActiveSources.
-
#paginate(*args) ⇒ Object
The pagination will also use the prepare_options! to have access to the advanced finder options.
- #property_options_for(property) ⇒ Object
-
#props_to_destroy ⇒ Object
All the options that should be destroy for :dependent => :destroy settings.
-
#rewrite(id, attributes) ⇒ Object
Like update, only that it will overwrite the given attributes instead of adding to themƒ.
-
#split_attribute_hash(attributes) ⇒ Object
Splits the attribute hash that is given for new, update and the like.
-
#update(id, attributes) ⇒ Object
Semantic version of ActiveRecord::Base#update - the id may be a record id or an URL, and the attributes may contain semantic attributes.
-
#value_for(thing) ⇒ Object
If will return itself unless the value is a SemanticProperty, in which case it will return the property’s value.
Instance Method Details
#additional_rdf_types ⇒ Object
Accessor for additional rdf types that will automatically be added to each object of that Source class
15 16 17 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 15 def additional_rdf_types @additional_rdf_types ||= [] end |
#create_from_xml(xml, options = {}) ⇒ Object
Create sources from XML. The result is either a single source or an Array of sources, depending on wether the XML contains multiple sources.
The imported sources will be saved during import, to ensure that relations between them are resolved correctly. If one of the imported elements does already exist, the existing source will be rewritten using ActiveSource#rewrite_attributes
The options may contain:
- reader
-
The reader class that the import should use
- progressor
-
The progress reporting object, which must respond to run_with_progress(message, size, &block)
- errors
-
If given, all erors will be looged to this array instead of raising an exception. See the create_multi_from method for more.
- duplicates
-
How to treat alredy existing sources. See ImportJobHelper for more documentation
- base_file_uri
-
The base uri to import file from
88 89 90 91 92 93 94 95 96 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 88 def create_from_xml(xml, = {}) . .assert_valid_keys(:reader, :progressor, :errors, :duplicates, :base_file_uri) reader = [:reader] ? .delete(:reader).to_s.classify.constantize : TaliaCore::ActiveSourceParts::Xml::SourceReader source_properties = reader.sources_from(xml, [:progressor], .delete(:base_file_uri)) self.progressor = .delete(:progressor) sources = create_multi_from(source_properties, ) (sources.size > 1) ? sources : sources.first end |
#create_multi_from(sources, options = {}) ⇒ Object
Creates multiple sources from the given array of attribute hashes. The sources are saved during import, ensuring that the relations are resolved correctly.
Options:
- errors
-
If given, all erors will be logged to this array instead of raising an exception. Each “entry” in the error array will be an Error object containing the origianl stack trace of the error
- duplicates
-
Indicates how to deal with sources that already exist in the datastore. See the ImportJobHelper class for a documentation of this option. Default is :skip
109 110 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 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 109 def create_multi_from(sources, = {}) . .assert_valid_keys(:errors, :duplicates) source_objects = [] run_with_progress('Writing imported', sources.size) do |progress| source_objects = sources.collect do |props| props. src = nil begin props[:uri] = uri_string_for(props[:uri], false) assit(props[:uri], "Must have a valid uri at this step") if(src = ActiveSource.find(:first, :conditions => { :uri => props[:uri] })) src.update_source(props, [:duplicates]) else src = ActiveSource.create_source(props) end src.save! rescue Exception => e if([:errors]) err = Errors::ImportError.new("ERROR during import of #{props[:uri]}: #{e.}") err.set_backtrace(e.backtrace) [:errors] << err TaliaCore.logger.warn("Problems importing #{props[:uri]} (logged): #{e.}") else raise end end progress.inc src end end source_objects end |
#create_source(args) ⇒ Object
Retrieves a new source with the given type. This gets a propety hash like #new, but it will correctly initialize a source of the type given in the hash. If no type is given, this will create a plain ActiveSource.
65 66 67 68 69 70 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 65 def create_source(args) args. type = args.delete(:type) || 'TaliaCore::ActiveSource' klass = type.constantize klass.new(args) end |
#db_attr?(attribute) ⇒ Boolean
Returns true if the given attribute is one that is stored in the database
184 185 186 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 184 def db_attr?(attribute) db_attributes.include?(attribute.to_s) end |
#defined_property?(prop_name) ⇒ Boolean
241 242 243 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 241 def defined_property?(prop_name) defined_props.include?(prop_name.to_s) || superclass.try_call.defined_property?(prop_name.to_s) end |
#exists?(value) ⇒ Boolean
This method is slightly expanded to allow passing uris and uri objects as an “id”
145 146 147 148 149 150 151 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 145 def exists?(value) if(uri_s = uri_string_for(value)) super(:uri => uri_s) else super end end |
#expand_uri(uri) ⇒ Object
Tries to expand a generic URI value that is either given as a full URL or a namespace:name value.
This will assume a full URL if it finds a “:/” string inside the URI. Otherwise it will construct a namespace - name URI
193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 193 def (uri) # TODO: Merge with uri_for ? assit_block do |errors| unless(uri.respond_to?(:uri) || uri.kind_of?(String)) || uri.kind_of?(Symbol) errors << "Found strange object of type #{uri.class}" end true end uri = uri.respond_to?(:uri) ? uri.uri.to_s : uri.to_s return uri if(uri.include?(':/')) N::URI.make_uri(uri).to_s end |
#new(*args) ⇒ Object
New method for ActiveSources. If a URL of an existing Source is given as the only parameter, that source will be returned. This makes the class work smoothly with our ActiveRDF version query interface.
Note that any semantic properties that were passed in to the constructor will be assigned after the ActiveRecord “create” callbacks have been called.
The option hash may contain a “files” option, which can be used to add data files directly on creation. This will call the attach_files method on the object.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 28 def new(*args) the_source = if((args.size == 1) && (args.first.is_a?(Hash))) = args.first . # We have an option hash to init the source files = .delete(:files) [:uri] = uri_string_for([:uri], false) if(autofill_overwrites?) [:uri] = auto_uri elsif(autofill_uri?) [:uri] ||= auto_uri end attributes = split_attribute_hash() the_source = super(attributes[:db_attributes]) the_source.add_semantic_attributes(false, attributes[:semantic_attributes]) the_source.attach_files(files) if(files) the_source elsif(args.size == 1 && ( uri_s = uri_string_for(args[0]))) # One string argument should be the uri # Either the current object from the db, or a new one if it doesn't exist in the db find(:first, :conditions => { :uri => uri_s } ) || super(:uri => uri_s) elsif(args.size == 0 && autofill_uri?) auto = auto_uri raise(ArgumentError, "Record already exists #{auto}") if(ActiveSource.exists?(auto)) super(:uri => auto) else # In this case, it's a generic "new" call super end the_source.add_additional_rdf_types if(the_source.new_record?) the_source end |
#paginate(*args) ⇒ Object
The pagination will also use the prepare_options! to have access to the advanced finder options
172 173 174 175 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 172 def paginate(*args) (args.last) if(args.last.is_a?(Hash)) super end |
#property_options_for(property) ⇒ Object
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 230 def (property) property = defined_props[property.to_s] if(defined_props[property.to_s]) = [property.to_s] = superclass.try_call.(property) if( && ) .merge() else || || {} end end |
#props_to_destroy ⇒ Object
All the options that should be destroy for :dependent => :destroy settings
246 247 248 249 250 251 252 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 246 def props_to_destroy to_destroy = (superclass.try_call.props_to_destroy || []) .each do |prop, | to_destroy << prop if([:dependent] == :destroy) end to_destroy end |
#rewrite(id, attributes) ⇒ Object
Like update, only that it will overwrite the given attributes instead of adding to themƒ
164 165 166 167 168 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 164 def rewrite(id, attributes) record = find(id) raise(ActiveRecord::RecordNotFound) unless(record) record.rewrite_attributes(attributes) end |
#split_attribute_hash(attributes) ⇒ Object
Splits the attribute hash that is given for new, update and the like. This will return another hash, where result will contain the hash of the database attributes while result will contain the other attributes.
The semantic attributes will be expanded to full URIs whereever possible.
This method will not check for attributes that correspond to singular property names.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 214 def split_attribute_hash(attributes) assit_kind_of(Hash, attributes) db_attributes = {} semantic_attributes = {} attributes.each do |field, value| if(db_attr?(field)) db_attributes[field] = value elsif(defined_property?(field)) semantic_attributes[field] = value else semantic_attributes[(field)] = value end end { :semantic_attributes => semantic_attributes, :db_attributes => db_attributes } end |
#update(id, attributes) ⇒ Object
Semantic version of ActiveRecord::Base#update - the id may be a record id or an URL, and the attributes may contain semantic attributes. See the update_attributes method for details on how the semantic attributes behave.
156 157 158 159 160 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 156 def update(id, attributes) record = find(id) raise(ActiveRecord::RecordNotFound) unless(record) record.update_attributes(attributes) end |
#value_for(thing) ⇒ Object
If will return itself unless the value is a SemanticProperty, in which case it will return the property’s value.
179 180 181 |
# File 'lib/talia_core/active_source_parts/class_methods.rb', line 179 def value_for(thing) thing.is_a?(SemanticProperty) ? thing.value : thing end |