caruby-core 1.4.9 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +48 -0
- data/lib/caruby/cli/command.rb +2 -1
- data/lib/caruby/csv/csv_mapper.rb +8 -8
- data/lib/caruby/database/persistable.rb +44 -65
- data/lib/caruby/database/persistence_service.rb +12 -9
- data/lib/caruby/database/persistifier.rb +14 -14
- data/lib/caruby/database/reader.rb +53 -51
- data/lib/caruby/database/search_template_builder.rb +9 -10
- data/lib/caruby/database/store_template_builder.rb +58 -58
- data/lib/caruby/database/writer.rb +96 -96
- data/lib/caruby/database.rb +19 -19
- data/lib/caruby/domain/attribute.rb +581 -0
- data/lib/caruby/domain/attributes.rb +615 -0
- data/lib/caruby/domain/dependency.rb +240 -0
- data/lib/caruby/domain/importer.rb +183 -0
- data/lib/caruby/domain/introspection.rb +176 -0
- data/lib/caruby/domain/inverse.rb +173 -0
- data/lib/caruby/domain/inversible.rb +1 -2
- data/lib/caruby/domain/java_attribute.rb +173 -0
- data/lib/caruby/domain/merge.rb +13 -10
- data/lib/caruby/domain/metadata.rb +141 -0
- data/lib/caruby/domain/mixin.rb +35 -0
- data/lib/caruby/domain/reference_visitor.rb +5 -3
- data/lib/caruby/domain.rb +340 -0
- data/lib/caruby/import/java.rb +29 -25
- data/lib/caruby/migration/migratable.rb +5 -5
- data/lib/caruby/migration/migrator.rb +19 -15
- data/lib/caruby/migration/resource_module.rb +1 -1
- data/lib/caruby/resource.rb +39 -30
- data/lib/caruby/util/collection.rb +94 -33
- data/lib/caruby/util/coordinate.rb +28 -2
- data/lib/caruby/util/log.rb +4 -4
- data/lib/caruby/util/module.rb +12 -28
- data/lib/caruby/util/partial_order.rb +9 -10
- data/lib/caruby/util/pretty_print.rb +46 -26
- data/lib/caruby/util/topological_sync_enumerator.rb +10 -4
- data/lib/caruby/util/transitive_closure.rb +2 -2
- data/lib/caruby/util/visitor.rb +1 -1
- data/lib/caruby/version.rb +1 -1
- data/test/lib/caruby/database/persistable_test.rb +1 -1
- data/test/lib/caruby/domain/domain_test.rb +14 -28
- data/test/lib/caruby/domain/inversible_test.rb +1 -1
- data/test/lib/caruby/import/java_test.rb +5 -0
- data/test/lib/caruby/migration/test_case.rb +0 -1
- data/test/lib/caruby/test_case.rb +9 -10
- data/test/lib/caruby/util/collection_test.rb +23 -5
- data/test/lib/caruby/util/module_test.rb +10 -14
- data/test/lib/caruby/util/partial_order_test.rb +16 -15
- data/test/lib/caruby/util/visitor_test.rb +1 -1
- data/test/lib/examples/galena/clinical_trials/migration/test_case.rb +1 -1
- metadata +16 -15
- data/History.txt +0 -44
- data/lib/caruby/domain/attribute_metadata.rb +0 -551
- data/lib/caruby/domain/java_attribute_metadata.rb +0 -183
- data/lib/caruby/domain/resource_attributes.rb +0 -565
- data/lib/caruby/domain/resource_dependency.rb +0 -217
- data/lib/caruby/domain/resource_introspection.rb +0 -160
- data/lib/caruby/domain/resource_inverse.rb +0 -151
- data/lib/caruby/domain/resource_metadata.rb +0 -155
- data/lib/caruby/domain/resource_module.rb +0 -370
- data/lib/caruby/yard/resource_metadata_handler.rb +0 -8
@@ -1,183 +0,0 @@
|
|
1
|
-
require 'caruby/util/inflector'
|
2
|
-
require 'caruby/domain/attribute_metadata'
|
3
|
-
|
4
|
-
module CaRuby
|
5
|
-
# The attribute metadata for an introspected Java property.
|
6
|
-
class JavaAttributeMetadata < AttributeMetadata
|
7
|
-
|
8
|
-
# This attribute's Java property descriptor.
|
9
|
-
attr_reader :property_descriptor
|
10
|
-
|
11
|
-
# This attribute's Java property [reader, writer] accessors, e.g. +[:getActivityStatus, :setActivityStatus]+.
|
12
|
-
attr_reader :property_accessors
|
13
|
-
|
14
|
-
# Creates a Ruby Attribute symbol corresponding to the given Ruby Java class wrapper klazz
|
15
|
-
# and Java property_descriptor.
|
16
|
-
#
|
17
|
-
# The attribute name is the lower-case, underscore property descriptor name with the alterations
|
18
|
-
# described in {JavaAttributeMetadata.to_attribute_symbol} and {Class#unocclude_reserved_method}.
|
19
|
-
#
|
20
|
-
# The attribute type is inferred as follows:
|
21
|
-
# * If the property descriptor return type is a primitive Java type, then that type is returned.
|
22
|
-
# * If the return type is a parameterized collection, then the parameter type is returned.
|
23
|
-
# * If the return type is an unparameterized collection, then this method infers the type from
|
24
|
-
# the property name, e.g. +StudyProtocolCollection+type is inferred as +StudyProtocol+
|
25
|
-
# by stripping the +Collection+ suffix, capitalizing the prefix and looking for a class of
|
26
|
-
# that name in the {ResourceMetadata#domain_module}.
|
27
|
-
# * If the declarer class metadata configuration includes a +domain_attributes+ property, then
|
28
|
-
# the type specified in that property is returned.
|
29
|
-
# * Otherwise, this method returns Java::Javalang::Object.
|
30
|
-
#
|
31
|
-
# The optional restricted_type argument restricts the attribute to a subclass of the declared
|
32
|
-
# property type.
|
33
|
-
def initialize(pd, declarer, restricted_type=nil)
|
34
|
-
symbol = create_standard_attribute_symbol(pd, declarer)
|
35
|
-
super(symbol, declarer, restricted_type)
|
36
|
-
@property_descriptor = pd
|
37
|
-
# deficient Java introspector does not recognize 'is' prefix for a Boolean property
|
38
|
-
rm = declarer.property_read_method(pd)
|
39
|
-
raise ArgumentError.new("Property does not have a read method: #{declarer.qp}.#{pd.name}") unless rm
|
40
|
-
reader = rm.name.to_sym
|
41
|
-
unless declarer.method_defined?(reader) then
|
42
|
-
reader = "is#{reader.to_s.capitalize_first}".to_sym
|
43
|
-
unless declarer.method_defined?(reader) then
|
44
|
-
raise ArgumentError.new("Reader method not found for #{declarer} property #{pd.name}")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
unless pd.write_method then
|
48
|
-
raise ArgumentError.new("Property does not have a write method: #{declarer.qp}.#{pd.name}")
|
49
|
-
end
|
50
|
-
writer = pd.write_method.name.to_sym
|
51
|
-
unless declarer.method_defined?(writer) then
|
52
|
-
raise ArgumentError.new("Writer method not found for #{declarer} property #{pd.name}")
|
53
|
-
end
|
54
|
-
@property_accessors = [reader, writer]
|
55
|
-
qualify(:collection) if collection_java_class?
|
56
|
-
end
|
57
|
-
|
58
|
-
# @return [Symbol] the JRuby wrapper method for the Java property reader
|
59
|
-
def property_reader
|
60
|
-
property_accessors.first
|
61
|
-
end
|
62
|
-
|
63
|
-
# @return [Symbol] the JRuby wrapper method for the Java property writer
|
64
|
-
def property_writer
|
65
|
-
property_accessors.last
|
66
|
-
end
|
67
|
-
|
68
|
-
def type
|
69
|
-
@type ||= infer_type
|
70
|
-
end
|
71
|
-
|
72
|
-
# Returns a lower-case, underscore symbol for the given property_name.
|
73
|
-
# A name ending in 'Collection' is changed to a pluralization.
|
74
|
-
#
|
75
|
-
# @example
|
76
|
-
# JavaAttributeMetadata.to_attribute_symbol('specimenEventCollection') #=> :specimen_events
|
77
|
-
def self.to_attribute_symbol(property_name)
|
78
|
-
name = if property_name =~ /(.+)Collection$/ then
|
79
|
-
property_name[0...-'Collection'.length].pluralize.underscore
|
80
|
-
else
|
81
|
-
property_name.underscore
|
82
|
-
end
|
83
|
-
name.to_sym
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
|
88
|
-
# @param pd the Java property descriptor
|
89
|
-
# @param [Class] klass the declarer
|
90
|
-
# @return [String] the lower-case, underscore symbol for the given property descriptor
|
91
|
-
def create_standard_attribute_symbol(pd, klass)
|
92
|
-
propname = pd.name
|
93
|
-
name = propname.underscore
|
94
|
-
renamed = klass.unocclude_reserved_method(pd)
|
95
|
-
if renamed then
|
96
|
-
logger.debug { "Renamed #{klass.qp} reserved Ruby method #{name} to #{renamed}." }
|
97
|
-
renamed
|
98
|
-
else
|
99
|
-
JavaAttributeMetadata.to_attribute_symbol(propname)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# @return [Boolean] whether this property's Java type is +Iterable+
|
104
|
-
def collection_java_class?
|
105
|
-
# the Java property type
|
106
|
-
ptype = @property_descriptor.property_type
|
107
|
-
# Test whether the corresponding JRuby wrapper class or module is an Iterable.
|
108
|
-
Class.to_ruby(ptype) < Java::JavaLang::Iterable
|
109
|
-
end
|
110
|
-
|
111
|
-
# @return [Class] the type for the specified klass property descriptor pd as described in {#initialize}
|
112
|
-
def infer_type
|
113
|
-
collection_java_class? ? infer_collection_type : infer_non_collection_type
|
114
|
-
end
|
115
|
-
|
116
|
-
# Returns the domain type for this attribute's Java Collection property descriptor.
|
117
|
-
# If the property type is parameterized by a single domain class, then that generic type argument is the domain type.
|
118
|
-
# Otherwise, the type is inferred from the property name as described in {#infer_collection_type_from_name}.
|
119
|
-
#
|
120
|
-
# @return [Class] this property's Ruby type
|
121
|
-
def infer_collection_type
|
122
|
-
generic_parameter_type or infer_collection_type_from_name or Java::JavaLang::Object
|
123
|
-
end
|
124
|
-
|
125
|
-
# @return [Class] this property's Ruby type
|
126
|
-
def infer_non_collection_type
|
127
|
-
jtype = @property_descriptor.property_type
|
128
|
-
if jtype.primitive then
|
129
|
-
Class.to_ruby(jtype)
|
130
|
-
else
|
131
|
-
@declarer.domain_module.domain_type_with_name(jtype.name) or Class.to_ruby(jtype)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# @return [Class, nil] the Ruby type as determined by the configuration, if any
|
136
|
-
def configured_type
|
137
|
-
name = @declarer.class.configuration.domain_type_name(to_sym) || return
|
138
|
-
@declarer.domain_module.domain_type_with_name(name) or java_to_ruby_class(name)
|
139
|
-
end
|
140
|
-
|
141
|
-
# @return [Class, nil] the domain type of this attribute's property descriptor Collection generic
|
142
|
-
# type argument, or nil if none
|
143
|
-
def generic_parameter_type
|
144
|
-
method = @property_descriptor.readMethod || return
|
145
|
-
gtype = method.genericReturnType
|
146
|
-
return unless Java::JavaLangReflect::ParameterizedType === gtype
|
147
|
-
atypes = gtype.actualTypeArguments
|
148
|
-
return unless atypes.size == 1
|
149
|
-
atype = atypes[0]
|
150
|
-
klass = java_to_ruby_class(atype)
|
151
|
-
logger.debug { "Inferred #{declarer.qp} #{self} domain type #{klass.qp} from generic parameter #{atype.name}." } if klass
|
152
|
-
klass
|
153
|
-
end
|
154
|
-
|
155
|
-
# @param [Class, String] jtype the Java class or class name
|
156
|
-
# @return [Class] the corresponding Ruby type
|
157
|
-
def java_to_ruby_class(jtype)
|
158
|
-
name = String === jtype ? jtype : jtype.name
|
159
|
-
@declarer.domain_module.domain_type_with_name(name) or Class.to_ruby(name)
|
160
|
-
end
|
161
|
-
|
162
|
-
# Returns the domain type for this attribute's collection Java property descriptor name.
|
163
|
-
# By convention, caBIG domain collection properties often begin with a domain type
|
164
|
-
# name and end in 'Collection'. This method strips the Collection suffix and checks
|
165
|
-
# whether the prefix is a domain class.
|
166
|
-
#
|
167
|
-
# For example, the type of the property named +distributionProtocolCollection+
|
168
|
-
# is inferred as +DistributionProtocol+ by stripping the +Collection+ suffix,
|
169
|
-
# capitalizing the prefix and looking for a class of that name in this classifier's
|
170
|
-
# domain_module.
|
171
|
-
#
|
172
|
-
# @return [Class] the collection item type
|
173
|
-
def infer_collection_type_from_name
|
174
|
-
prop_name = @property_descriptor.name
|
175
|
-
index = prop_name =~ /Collection$/
|
176
|
-
index ||= prop_name.length
|
177
|
-
prefix = prop_name[0...1].upcase + prop_name[1...index]
|
178
|
-
klass = @declarer.domain_module.domain_type_with_name(prefix)
|
179
|
-
if klass then logger.debug { "Inferred #{declarer.qp} #{self} collection domain type #{klass.qp} from the attribute name." } end
|
180
|
-
klass
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|