caruby-core 1.4.2 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/History.txt +10 -0
  2. data/lib/caruby/cli/command.rb +10 -8
  3. data/lib/caruby/database/fetched_matcher.rb +28 -39
  4. data/lib/caruby/database/lazy_loader.rb +101 -0
  5. data/lib/caruby/database/persistable.rb +190 -167
  6. data/lib/caruby/database/persistence_service.rb +21 -7
  7. data/lib/caruby/database/persistifier.rb +185 -0
  8. data/lib/caruby/database/reader.rb +106 -176
  9. data/lib/caruby/database/saved_matcher.rb +56 -0
  10. data/lib/caruby/database/search_template_builder.rb +1 -1
  11. data/lib/caruby/database/sql_executor.rb +8 -7
  12. data/lib/caruby/database/store_template_builder.rb +134 -61
  13. data/lib/caruby/database/writer.rb +252 -52
  14. data/lib/caruby/database.rb +88 -67
  15. data/lib/caruby/domain/attribute_initializer.rb +16 -0
  16. data/lib/caruby/domain/attribute_metadata.rb +161 -72
  17. data/lib/caruby/domain/id_alias.rb +22 -0
  18. data/lib/caruby/domain/inversible.rb +91 -0
  19. data/lib/caruby/domain/merge.rb +116 -35
  20. data/lib/caruby/domain/properties.rb +1 -1
  21. data/lib/caruby/domain/reference_visitor.rb +207 -71
  22. data/lib/caruby/domain/resource_attributes.rb +93 -80
  23. data/lib/caruby/domain/resource_dependency.rb +22 -97
  24. data/lib/caruby/domain/resource_introspection.rb +21 -28
  25. data/lib/caruby/domain/resource_inverse.rb +134 -0
  26. data/lib/caruby/domain/resource_metadata.rb +41 -19
  27. data/lib/caruby/domain/resource_module.rb +42 -33
  28. data/lib/caruby/import/java.rb +8 -9
  29. data/lib/caruby/migration/migrator.rb +20 -7
  30. data/lib/caruby/migration/resource_module.rb +0 -2
  31. data/lib/caruby/resource.rb +132 -351
  32. data/lib/caruby/util/cache.rb +4 -1
  33. data/lib/caruby/util/class.rb +48 -1
  34. data/lib/caruby/util/collection.rb +54 -18
  35. data/lib/caruby/util/inflector.rb +7 -0
  36. data/lib/caruby/util/options.rb +35 -31
  37. data/lib/caruby/util/partial_order.rb +1 -1
  38. data/lib/caruby/util/properties.rb +2 -2
  39. data/lib/caruby/util/stopwatch.rb +16 -8
  40. data/lib/caruby/util/transitive_closure.rb +1 -1
  41. data/lib/caruby/util/visitor.rb +342 -328
  42. data/lib/caruby/version.rb +1 -1
  43. data/lib/caruby/yard/resource_metadata_handler.rb +8 -0
  44. data/lib/caruby.rb +2 -0
  45. metadata +10 -9
  46. data/lib/caruby/database/saved_merger.rb +0 -131
  47. data/lib/caruby/domain/annotatable.rb +0 -25
  48. data/lib/caruby/domain/annotation.rb +0 -23
  49. data/lib/caruby/import/annotatable_class.rb +0 -28
  50. data/lib/caruby/import/annotation_class.rb +0 -27
  51. data/lib/caruby/import/annotation_module.rb +0 -67
  52. data/lib/caruby/migration/resource.rb +0 -8
@@ -1,3 +1,3 @@
1
1
  module CaRuby
2
- VERSION = "1.4.2"
2
+ VERSION = "1.4.3"
3
3
  end
@@ -0,0 +1,8 @@
1
+ class ResourceMetadataHandler < YARD::Handlers::Ruby::Legacy::AttributeHandler
2
+ handles method_call(/\Aqualify_attribute\b/)
3
+ namespace_only
4
+
5
+ def process
6
+ push_state(:scope => :class) { super }
7
+ end
8
+ end
data/lib/caruby.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'caruby/resource'
2
+
1
3
  # CaRuby is a JRuby facade for the caBIG application APIs.
2
4
  # See the [http://http://caruby.rubyforge.org/](caRuby) home page for more information.
3
5
  module CaRuby;end
metadata CHANGED
@@ -6,11 +6,11 @@ executables: []
6
6
 
7
7
  version: !ruby/object:Gem::Version
8
8
  prerelease: false
9
- version: 1.4.2
9
+ version: 1.4.3
10
10
  segments:
11
11
  - 1
12
12
  - 4
13
- - 2
13
+ - 3
14
14
  post_install_message:
15
15
  date: 2010-11-30 08:00:00 +00:00
16
16
  files:
@@ -28,17 +28,20 @@ files:
28
28
  - lib/caruby/csv/csv_mapper.rb
29
29
  - lib/caruby/csv/csvio.rb
30
30
  - lib/caruby/database/fetched_matcher.rb
31
+ - lib/caruby/database/lazy_loader.rb
31
32
  - lib/caruby/database/persistable.rb
32
33
  - lib/caruby/database/persistence_service.rb
34
+ - lib/caruby/database/persistifier.rb
33
35
  - lib/caruby/database/reader.rb
34
- - lib/caruby/database/saved_merger.rb
36
+ - lib/caruby/database/saved_matcher.rb
35
37
  - lib/caruby/database/search_template_builder.rb
36
38
  - lib/caruby/database/sql_executor.rb
37
39
  - lib/caruby/database/store_template_builder.rb
38
40
  - lib/caruby/database/writer.rb
39
- - lib/caruby/domain/annotatable.rb
40
- - lib/caruby/domain/annotation.rb
41
+ - lib/caruby/domain/attribute_initializer.rb
41
42
  - lib/caruby/domain/attribute_metadata.rb
43
+ - lib/caruby/domain/id_alias.rb
44
+ - lib/caruby/domain/inversible.rb
42
45
  - lib/caruby/domain/java_attribute_metadata.rb
43
46
  - lib/caruby/domain/merge.rb
44
47
  - lib/caruby/domain/properties.rb
@@ -46,16 +49,13 @@ files:
46
49
  - lib/caruby/domain/resource_attributes.rb
47
50
  - lib/caruby/domain/resource_dependency.rb
48
51
  - lib/caruby/domain/resource_introspection.rb
52
+ - lib/caruby/domain/resource_inverse.rb
49
53
  - lib/caruby/domain/resource_metadata.rb
50
54
  - lib/caruby/domain/resource_module.rb
51
55
  - lib/caruby/domain/uniquify.rb
52
- - lib/caruby/import/annotatable_class.rb
53
- - lib/caruby/import/annotation_class.rb
54
- - lib/caruby/import/annotation_module.rb
55
56
  - lib/caruby/import/java.rb
56
57
  - lib/caruby/migration/migratable.rb
57
58
  - lib/caruby/migration/migrator.rb
58
- - lib/caruby/migration/resource.rb
59
59
  - lib/caruby/migration/resource_module.rb
60
60
  - lib/caruby/migration/uniquify.rb
61
61
  - lib/caruby/util/attribute_path.rb
@@ -86,6 +86,7 @@ files:
86
86
  - lib/caruby/util/version.rb
87
87
  - lib/caruby/util/visitor.rb
88
88
  - lib/caruby/util/weak_hash.rb
89
+ - lib/caruby/yard/resource_metadata_handler.rb
89
90
  - History.txt
90
91
  - LEGAL
91
92
  - LICENSE
@@ -1,131 +0,0 @@
1
- require 'caruby/util/collection'
2
- require 'caruby/util/pretty_print'
3
- require 'caruby/domain/reference_visitor'
4
- require 'caruby/database/fetched_matcher'
5
- require 'caruby/database/store_template_builder'
6
-
7
- module CaRuby
8
- class Database
9
- # Merges database content sources into saved targets.
10
- class SavedMerger
11
- # @param [Database] database the database performing the save
12
- def initialize(database)
13
- @database = database
14
- # the save result matchers
15
- cr_mtchr = FetchedMatcher.new(:relaxed)
16
- upd_mtchr = FetchedMatcher.new
17
- # the save result merge visitors
18
- @cr_mrg_vstr = MergeVisitor.new(:matcher => cr_mtchr) { |src, tgt| mergeable_saved_attributes(tgt) }
19
- @upd_mrg_vstr = MergeVisitor.new(:matcher => upd_mtchr) { |src, tgt| mergeable_saved_attributes(tgt) }
20
- end
21
-
22
-
23
- # Merges the database content into the given saved domain object.
24
- # Dependents are merged recursively.
25
- #
26
- # @param [Resource] obj the saved domain object
27
- # @param [Resource] result the caCORE result
28
- # @return [Resource] the object representing the persistent state
29
- def merge(saved, result)
30
- # the sync source reflecting the database content
31
- src = saved_source(saved, result)
32
- # merge the source into obj, including all cascaded dependents
33
- merge_saved(saved, src)
34
- src
35
- end
36
-
37
- # @param [Resource] obj the saved domain object
38
- # @param [Resource] result the caCORE result domain object
39
- # @return [Resource] the source domain object which accurately reflects the database state
40
- # @see #fetch_saved?
41
- def saved_source(obj, result)
42
- # The true stored content might need to be fetched from the database.
43
- if obj.fetch_saved? then
44
- tmpl = result.copy(:identifier)
45
- logger.debug { "Fetching saved #{obj.qp} using template #{tmpl}..." }
46
- tmpl.find
47
- else
48
- result
49
- end
50
- end
51
-
52
- # Merges the content of the source domain object into the saved domain object obj.
53
- # If obj differs from source, then obj is resaved. Dependents are merged recursively.
54
- #
55
- # @param [Resource] obj the saved domain object
56
- # @param [Resource] source object holding the stored content
57
- def merge_saved(obj, source)
58
- logger.debug { "Merging database content #{source} into saved #{obj.qp}..." }
59
- visitor = @database.mergeable_autogenerated_operation? ? @cr_mrg_vstr : @upd_mrg_vstr
60
- visitor.visit(obj, source) do |tgt, src|
61
- logger.debug { "Saved #{obj.qp} merge visitor merged database content #{src.qp} into #{tgt.qp}..." }
62
- merge_saved_reference(tgt, src)
63
- end
64
- end
65
-
66
- # Sets the target snapshot attribute values from the given source, if different.
67
- #
68
- # @param [Resource] target the saved domain object
69
- # @param [Resource] source the domain object reflecting the database state
70
- # @return [Resource] the synced target
71
- def merge_saved_reference(target, source)
72
- # set each unsaved non-domain attribute from the source to reflect the database value
73
- target.copy_volatile_attributes(source)
74
-
75
- # take a snapshot of the saved target
76
- target.take_snapshot
77
- logger.debug { "A snapshot was taken of the saved #{target.qp}." }
78
-
79
- # the non-domain attribute => [target value, source value] difference hash
80
- diff = target.diff(source)
81
- # the difference attribute => source value hash, excluding nil source values
82
- dvh = diff.transform { |vdiff| vdiff.last }.compact
83
- return if dvh.empty?
84
- logger.debug { "Saved #{target} differs from database content #{source.qp} as follows: #{diff.filter_on_key { |attr| dvh.has_key?(attr) }.qp}" }
85
- logger.debug { "Setting saved #{target.qp} snapshot values from source values to reflect the database state: #{dvh.qp}..." }
86
- # update the snapshot from the source value to reflect the database state
87
- target.snapshot.merge!(dvh)
88
-
89
- target
90
- end
91
-
92
- # Returns the dependent attributes that can be copied from a save result to
93
- # the given save argument object. This method qualifies the obj class
94
- # {AttributeMetadata#copyable_saved_attributes} by whether the attribute is
95
- # actually auto-generated for the saved object, i.e. the object was itself
96
- # created or auto-generated. If obj was created or auto-generated, then
97
- # this method returns the {AttributeMetadata#copyable_saved_attributes}.
98
- # Otherwise, this method returns the {AttributeMetadata#cascaded_attributes}.
99
- #
100
- # @param [Resource] obj the domain object which was saved
101
- # @return [<Symbol>] the attributes to copy
102
- def mergeable_saved_attributes(obj)
103
- fa = obj.class.fetched_domain_attributes
104
- obj.suspend_lazy_loader do
105
- attrs = obj.class.cascaded_attributes.filter do |attr|
106
- fa.include?(attr) or not obj.send(attr).nil_or_empty?
107
- end
108
- if @database.mergeable_autogenerated_operation? then
109
- ag_attrs = mergeable_saved_autogenerated_attributes(obj)
110
- unless ag_attrs.empty? then
111
- logger.debug { "Adding #{obj.qp} mergeable saved auto-generated #{ag_attrs.to_series} to the merge set..." }
112
- attrs = attrs.to_set.merge(ag_attrs)
113
- end
114
- end
115
- logger.debug { "Mergeable saved #{obj.qp} attributes: #{attrs.qp}." } unless attrs.empty?
116
- attrs
117
- end
118
- end
119
-
120
- # Returns the autogenerated dependent attributes that can be copied from a save result to
121
- # the given save argument object.
122
- #
123
- # @param [Resource] obj the domain object which was saved
124
- # @return [<Symbol>] the attributes to copy, or nil if no such attributes
125
- def mergeable_saved_autogenerated_attributes(obj)
126
- attrs = obj.class.mergeable_saved_autogenerated_attributes
127
- attrs.reject { |attr| obj.send(attr).nil_or_empty? }
128
- end
129
- end
130
- end
131
- end
@@ -1,25 +0,0 @@
1
- require 'caruby/resource'
2
-
3
- module CaRuby
4
- # The Annotatable module marks a domain class as an anchor which holds at least one annotation attribute.
5
- module Annotatable
6
- include Resource
7
-
8
- # Dynamically creates a new annotation reference method with the given symbol if symbol is the camelized form of a
9
- # class in one of the Annotatable class's annotation modules.
10
- def method_missing(symbol, *args)
11
- name = symbol.to_s
12
- # remove trailing assignment = if present
13
- name.chop! if name =~ /=$/
14
- # the class with the camelized form of the name
15
- klass = self.class.annotation_class(name.camelize)
16
- # delegate to super to print an error if no class
17
- super if klass.nil?
18
- # add the annotation attribute
19
- klass.add_annotation(self.class)
20
- raise NotImplementedError.new("#{self.class.qp} annotation method not created: #{symbol}") unless respond_to?(symbol)
21
- #call the annotation attribute method
22
- send(symbol, *args)
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- require 'caruby/resource'
2
-
3
- module CaRuby
4
- # The Annotation module marks a domain object as an Annotation.
5
- module Annotation
6
- include Resource
7
-
8
- # Dynamically creates a new annotable owner attribute with the given symbol if symbol is an annotatable owner attribute
9
- # accessor method.
10
- #
11
- # @see #attribute_missing
12
- def method_missing(symbol, *args)
13
- name = symbol.to_s
14
- # remove trailing assignment = if present
15
- name.chop! if name =~ /=$/
16
- # try to make the owner attribute
17
- self.class.attribute_metadata(name.to_sym)
18
- # if we reached here, then the owner was created so verify and call the new method
19
- raise NoMethodError.new("#{name.demodulize} owner attribute #{name} created but accessor method not found: #{symbol}") unless method_defined?(symbol)
20
- send(symbol, *args)
21
- end
22
- end
23
- end
@@ -1,28 +0,0 @@
1
- require 'caruby/util/class'
2
- require 'caruby/util/collection'
3
- require 'caruby/import/annotation_module'
4
-
5
- module JavaImport
6
- # AnnotatableClass adds Annotation modules to an annotation anchor's domain module.
7
- module AnnotatableClass
8
-
9
- def self.extended(klass)
10
- klass.class_eval { include CaRuby::Annotatable }
11
- end
12
-
13
- def annotation_modules
14
- @annotation_modules ||= []
15
- end
16
-
17
- # Creates a new AnnotationModule anchored by this class for the given package and database service.
18
- def create_annotation_module(package, service)
19
- annotation_modules << AnnotationModule.create_annotation_module(self, package, service)
20
- end
21
-
22
- # Returns the class with the given unqualified name in one of this AnnotationClass's JavaImport::AnnotationModule
23
- # modules, or nil if no such class.
24
- def annotation_class(name)
25
- annotation_modules.detect_value { |mod| annotation_modules.const_get(name) rescue nil }
26
- end
27
- end
28
- end
@@ -1,27 +0,0 @@
1
- module JavaImport
2
- # AnnotationClass extends a domain class for an annotation class scoped by an annotation module.
3
- # The extended class must contain the +@anchor_class+ and +@annotation_module+ instance variables.
4
- module AnnotationClass
5
-
6
- # Dynamically creates a new reference attribute if the given attribute symbol is the underscore
7
- # form of this Annotation's anchor class.
8
- #
9
- #@param [Symbol] attribute the missing attribute
10
- def attribute_missing(attribute)
11
- # delegate to super to print an error if no class
12
- super unless attribute.to_s == anchor_class.qp.underscore
13
- # add the annotation attribute to the anchor class and the anchor attribute to this class
14
- anchor_class.add_annotation(self)
15
- end
16
-
17
- # @return [Class] the annotated class
18
- def anchor_class
19
- @anchor_class
20
- end
21
-
22
- # @return [Module] the module which scopes this AnnotationClass
23
- def annotation_module
24
- @annotation_module
25
- end
26
- end
27
- end
@@ -1,67 +0,0 @@
1
- require 'caruby/util/class'
2
- require 'caruby/util/collection'
3
- require 'caruby/import/importable'
4
- require 'caruby/import/annotation_class'
5
-
6
- module JavaImport
7
- # AnnotationModule creates annotation package modules within a domain module as a context for importing annotation classes.
8
- module AnnotationModule
9
- include Importable
10
-
11
- # Creates a new AnnotationModule in the given domain_module from the given annotation package and service.
12
- def self.create_annotation_module(anchor_class, package, service)
13
- domain_module = anchor_class.domain_module
14
- # make parent modules for each package component
15
- mod = package.split('.').inject(anchor_class.domain_module) do |parent, name|
16
- mod_id = name.camelize.to_sym
17
- if parent.const_defined?(mod_id) then
18
- parent.const_get(mod_id)
19
- else
20
- parent.const_set(mod_id, Module.new)
21
- end
22
- end
23
- # the terminal module is the AnnotationModule
24
- mod.extend(self)
25
- # initialize the java_package, service and empty access_properties
26
- mod.module_eval do
27
- @anchor_class = anchor_class
28
- @java_package = package
29
- @service = service
30
- @resource_module__props = CaRuby::Domain::Properties.new
31
- end
32
- mod_name = mod.name[anchor_class.domain_module.name.length..-1]
33
- logger.debug { "Created annotation module #{mod}." }
34
- mod
35
- end
36
-
37
- def java_package
38
- @java_package
39
- end
40
-
41
- def service
42
- @service
43
- end
44
-
45
- def anchor_class
46
- @anchor_class
47
- end
48
-
49
- def access_properties
50
- @resource_module__props
51
- end
52
-
53
- # Imports the domain Java class with specified class_name by delegating to Importable and
54
- # augmenting the importer to include CaRuby::Annotation in each imported class.
55
- def import_domain_class(class_name)
56
- anchor_class = @anchor_class
57
- ann_mod = self
58
- klass = super(class_name) do
59
- include CaRuby::Annotation
60
- @anchor_class = anchor_class
61
- @annotation_module = ann_mod
62
- yield if block_given?
63
- end
64
- klass.extend(AnnotationClass)
65
- end
66
- end
67
- end
@@ -1,8 +0,0 @@
1
- require 'caruby/resource'
2
- require 'caruby/migration/migratable'
3
-
4
- module CaRuby
5
- module Resource
6
- include Migratable
7
- end
8
- end