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.
- data/History.txt +10 -0
- data/lib/caruby/cli/command.rb +10 -8
- data/lib/caruby/database/fetched_matcher.rb +28 -39
- data/lib/caruby/database/lazy_loader.rb +101 -0
- data/lib/caruby/database/persistable.rb +190 -167
- data/lib/caruby/database/persistence_service.rb +21 -7
- data/lib/caruby/database/persistifier.rb +185 -0
- data/lib/caruby/database/reader.rb +106 -176
- data/lib/caruby/database/saved_matcher.rb +56 -0
- data/lib/caruby/database/search_template_builder.rb +1 -1
- data/lib/caruby/database/sql_executor.rb +8 -7
- data/lib/caruby/database/store_template_builder.rb +134 -61
- data/lib/caruby/database/writer.rb +252 -52
- data/lib/caruby/database.rb +88 -67
- data/lib/caruby/domain/attribute_initializer.rb +16 -0
- data/lib/caruby/domain/attribute_metadata.rb +161 -72
- data/lib/caruby/domain/id_alias.rb +22 -0
- data/lib/caruby/domain/inversible.rb +91 -0
- data/lib/caruby/domain/merge.rb +116 -35
- data/lib/caruby/domain/properties.rb +1 -1
- data/lib/caruby/domain/reference_visitor.rb +207 -71
- data/lib/caruby/domain/resource_attributes.rb +93 -80
- data/lib/caruby/domain/resource_dependency.rb +22 -97
- data/lib/caruby/domain/resource_introspection.rb +21 -28
- data/lib/caruby/domain/resource_inverse.rb +134 -0
- data/lib/caruby/domain/resource_metadata.rb +41 -19
- data/lib/caruby/domain/resource_module.rb +42 -33
- data/lib/caruby/import/java.rb +8 -9
- data/lib/caruby/migration/migrator.rb +20 -7
- data/lib/caruby/migration/resource_module.rb +0 -2
- data/lib/caruby/resource.rb +132 -351
- data/lib/caruby/util/cache.rb +4 -1
- data/lib/caruby/util/class.rb +48 -1
- data/lib/caruby/util/collection.rb +54 -18
- data/lib/caruby/util/inflector.rb +7 -0
- data/lib/caruby/util/options.rb +35 -31
- data/lib/caruby/util/partial_order.rb +1 -1
- data/lib/caruby/util/properties.rb +2 -2
- data/lib/caruby/util/stopwatch.rb +16 -8
- data/lib/caruby/util/transitive_closure.rb +1 -1
- data/lib/caruby/util/visitor.rb +342 -328
- data/lib/caruby/version.rb +1 -1
- data/lib/caruby/yard/resource_metadata_handler.rb +8 -0
- data/lib/caruby.rb +2 -0
- metadata +10 -9
- data/lib/caruby/database/saved_merger.rb +0 -131
- data/lib/caruby/domain/annotatable.rb +0 -25
- data/lib/caruby/domain/annotation.rb +0 -23
- data/lib/caruby/import/annotatable_class.rb +0 -28
- data/lib/caruby/import/annotation_class.rb +0 -27
- data/lib/caruby/import/annotation_module.rb +0 -67
- data/lib/caruby/migration/resource.rb +0 -8
@@ -4,7 +4,7 @@ require 'caruby/domain/java_attribute_metadata'
|
|
4
4
|
module CaRuby
|
5
5
|
# ResourceMetadata mix-in to infer attribute meta-data from Java properties.
|
6
6
|
module ResourceIntrospection
|
7
|
-
|
7
|
+
|
8
8
|
private
|
9
9
|
|
10
10
|
# Defines the Java property attribute and standard attribute methods, e.g.
|
@@ -106,6 +106,13 @@ module CaRuby
|
|
106
106
|
alias_method(writer, pwtr)
|
107
107
|
end
|
108
108
|
|
109
|
+
# Makes a standard attribute for the given property descriptor.
|
110
|
+
# Adds a camelized Java-like alias to the standard attribute.
|
111
|
+
#
|
112
|
+
# caTissue alert - DE annotation collection attributes are often misnamed,
|
113
|
+
# e.g. +histologic_grade+ for a +HistologicGrade+ collection attribute.
|
114
|
+
# This is fixed by adding a pluralized alias, e.g. +histologic_grades+.
|
115
|
+
#
|
109
116
|
# @return a new attribute symbol created for the given PropertyDescriptor pd
|
110
117
|
def create_java_attribute(pd)
|
111
118
|
# make the attribute metadata
|
@@ -115,6 +122,19 @@ module CaRuby
|
|
115
122
|
std_attr = attr_md.to_sym
|
116
123
|
prop_attr = pd.name.to_sym
|
117
124
|
delegate_to_attribute(prop_attr, std_attr) unless prop_attr == std_attr
|
125
|
+
|
126
|
+
# alias a misnamed collection attribute, if necessary
|
127
|
+
if attr_md.collection? then
|
128
|
+
name = std_attr.to_s
|
129
|
+
if name.singularize == name then
|
130
|
+
aliaz = name.pluralize.to_sym
|
131
|
+
if aliaz != name then
|
132
|
+
logger.debug { "Adding annotation #{qp} alias #{aliaz} to the misnamed collection attribute #{std_attr}..." }
|
133
|
+
delegate_to_attribute(aliaz, std_attr)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
118
138
|
std_attr
|
119
139
|
end
|
120
140
|
|
@@ -136,32 +156,5 @@ module CaRuby
|
|
136
156
|
offset_attr_accessor(hash, offset)
|
137
157
|
hash.each { |attr, original| add_attribute(attr, attribute_metadata(original).type) }
|
138
158
|
end
|
139
|
-
|
140
|
-
# Modifies the given attribute writer method if necessary to update the given inverse_attr value.
|
141
|
-
# This method is called on dependent and attributes qualified as inversible.
|
142
|
-
#
|
143
|
-
# @see ResourceDependency#add_owner
|
144
|
-
# @see ResourceAttributes#set_attribute_inverse
|
145
|
-
def add_inverse_updater(attribute, inverse)
|
146
|
-
attr_md = attribute_metadata(attribute)
|
147
|
-
# the reader and writer methods
|
148
|
-
reader, writer = attr_md.accessors
|
149
|
-
logger.debug { "Injecting inverse #{inverse} updater into #{qp}.#{attribute} writer method #{writer}..." }
|
150
|
-
# the inverse atttribute metadata
|
151
|
-
inv_attr_md = attr_md.inverse_attribute_metadata
|
152
|
-
# the inverse attribute reader and writer
|
153
|
-
inv_rdr, inv_wtr = inv_accessors = inv_attr_md.accessors
|
154
|
-
# redefine the writer method to update the inverse
|
155
|
-
# by delegating to the Resource instance set_inversible_attribute
|
156
|
-
redefine_method(writer) do |old_wtr|
|
157
|
-
# the attribute reader and (superseded) writer
|
158
|
-
accessors = [reader, old_wtr]
|
159
|
-
if inv_attr_md.collection? then
|
160
|
-
lambda { |owner| add_to_inverse_collection(owner, accessors, inv_rdr) }
|
161
|
-
else
|
162
|
-
lambda { |owner| set_inversible_noncollection_attribute(owner, accessors, inv_wtr) }
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
159
|
end
|
167
160
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'caruby/import/java'
|
2
|
+
require 'caruby/domain/java_attribute_metadata'
|
3
|
+
|
4
|
+
module CaRuby
|
5
|
+
# ResourceMetadata mix-in to infer and set inverse attributes.
|
6
|
+
module ResourceInverse
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Sets the given bi-directional association attribute's inverse.
|
11
|
+
#
|
12
|
+
# @param [Symbol] attribute the subject attribute
|
13
|
+
# @param [Symbol] the attribute inverse
|
14
|
+
# @raise [TypeError] if the inverse type is incompatible with this Resource
|
15
|
+
def set_attribute_inverse(attribute, inverse)
|
16
|
+
attr_md = attribute_metadata(attribute)
|
17
|
+
# return if inverse is already set
|
18
|
+
return if attr_md.inverse == inverse
|
19
|
+
# the default inverse
|
20
|
+
inverse ||= attr_md.type.detect_inverse_attribute(self)
|
21
|
+
# the inverse attribute meta-data
|
22
|
+
inv_md = attr_md.type.attribute_metadata(inverse)
|
23
|
+
# if the attribute is the many side of a 1:M relation, then delegate to the one side.
|
24
|
+
if attr_md.collection? and not inv_md.collection? then
|
25
|
+
return attr_md.type.set_attribute_inverse(inverse, attribute)
|
26
|
+
end
|
27
|
+
# this class must be the same as or a subclass of the inverse attribute type
|
28
|
+
unless self <= inv_md.type then
|
29
|
+
raise TypeError.new("Cannot set #{qp}.#{attribute} inverse to #{attr_md.type.qp}.#{attribute} with incompatible type #{inv_md.type.qp}")
|
30
|
+
end
|
31
|
+
|
32
|
+
# if the attribute is defined by this class, then set the inverse in the attribute metadata.
|
33
|
+
# otherwise, make a new attribute metadata specialized for this class.
|
34
|
+
unless attr_md.declarer == self then
|
35
|
+
attr_md = attr_md.dup
|
36
|
+
attr_md.declarer = self
|
37
|
+
add_attribute_metadata(attribute, inverse)
|
38
|
+
end
|
39
|
+
attr_md.inverse = inverse
|
40
|
+
|
41
|
+
# If attribute is the one side of a 1:M or non-reflexive 1:1 relation, then add the inverse updater.
|
42
|
+
unless attr_md.collection? then
|
43
|
+
add_inverse_updater(attribute, inverse)
|
44
|
+
unless attr_md.type == inv_md.type or inv_md.collection? then
|
45
|
+
attr_md.type.delegate_writer_to_inverse(inverse, attribute)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Detects an unambiguous attribute which refers to the given referencing class.
|
51
|
+
# If there is exactly one attribute with the given return type, then that attribute is chosen.
|
52
|
+
# Otherwise, the attribute whose name matches the underscored referencing class name is chosen,
|
53
|
+
# if any.
|
54
|
+
#
|
55
|
+
# @param [Class] klass the referencing class
|
56
|
+
# @return [Symbol, nil] the inverse attribute for the given referencing class and inverse,
|
57
|
+
# or nil if no owner attribute was detected
|
58
|
+
def detect_inverse_attribute(klass)
|
59
|
+
# the candidate attributes which return the referencing type
|
60
|
+
candidates = domain_attributes.compose { |attr_md| klass <= attr_md.type }.to_a
|
61
|
+
attr = detect_inverse_attribute_from_candidates(klass, candidates)
|
62
|
+
if attr then
|
63
|
+
logger.debug { "#{qp} #{klass.qp} inverse attribute is #{attr}." }
|
64
|
+
else
|
65
|
+
logger.debug { "#{qp} #{klass.qp} inverse attribute was not detected." }
|
66
|
+
end
|
67
|
+
attr
|
68
|
+
end
|
69
|
+
|
70
|
+
# Redefines the attribute writer method to delegate to its inverse writer.
|
71
|
+
# This is done to enforce inverse integrity.
|
72
|
+
#
|
73
|
+
# For a +Person+ attribute +account+ with inverse +holder+, this is equivalent to the following:
|
74
|
+
# class Person
|
75
|
+
# alias :set_account :account=
|
76
|
+
# def account=(acct)
|
77
|
+
# acct.holder = self if acct
|
78
|
+
# set_account(acct)
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
def delegate_writer_to_inverse(attribute, inverse)
|
82
|
+
attr_md = attribute_metadata(attribute)
|
83
|
+
# nothing to do if no inverse
|
84
|
+
inv_attr_md = attr_md.inverse_attribute_metadata || return
|
85
|
+
logger.debug { "Delegating #{qp}.#{attribute} update to the inverse #{attr_md.type.qp}.#{inv_attr_md}..." }
|
86
|
+
# redefine the write to set the dependent inverse
|
87
|
+
redefine_method(attr_md.writer) do |old_writer|
|
88
|
+
# delegate to the CaRuby::Resource set_inverse method
|
89
|
+
lambda { |dep| set_inverse(dep, old_writer, inv_attr_md.writer) }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# @param klass (see #detect_inverse_attribute)
|
96
|
+
# @param [<Symbol>] candidates the attributes constrained to the target type
|
97
|
+
# @return (see #detect_inverse_attribute)
|
98
|
+
def detect_inverse_attribute_from_candidates(klass, candidates)
|
99
|
+
return if candidates.empty?
|
100
|
+
# there can be at most one owner attribute per owner.
|
101
|
+
return candidates.first.to_sym if candidates.size == 1
|
102
|
+
# by convention, if more than one attribute references the owner type,
|
103
|
+
# then the attribute named after the owner type is the owner attribute
|
104
|
+
tgt = klass.name[/\w+$/].underscore.to_sym
|
105
|
+
tgt if candidates.detect { |attr| attr == tgt }
|
106
|
+
end
|
107
|
+
|
108
|
+
# Modifies the given attribute writer method if necessary to update the given inverse_attr value.
|
109
|
+
# This method is called on dependent and attributes qualified as inversible.
|
110
|
+
#
|
111
|
+
# @see #set_attribute_inverse
|
112
|
+
def add_inverse_updater(attribute, inverse)
|
113
|
+
attr_md = attribute_metadata(attribute)
|
114
|
+
# the reader and writer methods
|
115
|
+
rdr, wtr = attr_md.accessors
|
116
|
+
logger.debug { "Injecting inverse #{inverse} updater into #{qp}.#{attribute} writer method #{wtr}..." }
|
117
|
+
# the inverse atttribute metadata
|
118
|
+
inv_attr_md = attr_md.inverse_attribute_metadata
|
119
|
+
# the inverse attribute reader and writer
|
120
|
+
inv_rdr, inv_wtr = inv_accessors = inv_attr_md.accessors
|
121
|
+
|
122
|
+
# Redefine the writer method to update the inverse by delegating to the inverse
|
123
|
+
redefine_method(wtr) do |old_wtr|
|
124
|
+
# the attribute reader and (superseded) writer
|
125
|
+
accessors = [rdr, old_wtr]
|
126
|
+
if inv_attr_md.collection? then
|
127
|
+
lambda { |other| add_to_inverse_collection(other, accessors, inv_rdr) }
|
128
|
+
else
|
129
|
+
lambda { |other| set_inversible_noncollection_attribute(other, accessors, inv_wtr) }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'caruby/util/collection'
|
2
2
|
require 'caruby/import/java'
|
3
3
|
require 'caruby/domain/java_attribute_metadata'
|
4
|
-
require 'caruby/domain/resource_attributes'
|
5
4
|
require 'caruby/domain/resource_introspection'
|
5
|
+
require 'caruby/domain/resource_inverse'
|
6
6
|
require 'caruby/domain/resource_dependency'
|
7
|
+
require 'caruby/domain/resource_attributes'
|
7
8
|
|
8
9
|
module CaRuby
|
9
10
|
# Exception raised if a meta-data setting is missing or invalid.
|
@@ -11,7 +12,7 @@ module CaRuby
|
|
11
12
|
|
12
13
|
# Adds introspected metadata to a Class.
|
13
14
|
module ResourceMetadata
|
14
|
-
include ResourceIntrospection, ResourceDependency, ResourceAttributes
|
15
|
+
include ResourceIntrospection, ResourceInverse, ResourceDependency, ResourceAttributes
|
15
16
|
|
16
17
|
attr_reader :domain_module
|
17
18
|
|
@@ -21,7 +22,6 @@ module CaRuby
|
|
21
22
|
# by the {#domain_module} method.
|
22
23
|
def add_metadata(mod)
|
23
24
|
@domain_module = mod
|
24
|
-
init_attributes # in ResourceAttributes
|
25
25
|
introspect # in ResourceIntrospection
|
26
26
|
end
|
27
27
|
|
@@ -31,8 +31,43 @@ module CaRuby
|
|
31
31
|
attr_md.type if attr_md.domain?
|
32
32
|
end
|
33
33
|
|
34
|
+
# Returns an empty value for the given attribute.
|
35
|
+
# * If this class is not abstract, then the empty value is the initialized value.
|
36
|
+
# * Otherwise, if the attribute is a Java primitive number then zero.
|
37
|
+
# * Otherwise, if the attribute is a Java primitive boolean then +false+.
|
38
|
+
# * Otherwise, the empty value is nil.
|
39
|
+
#
|
40
|
+
# @param [Symbol] attribute the target attribute
|
41
|
+
# @return [Numeric, Boolean, Enumerable, nil] the empty attribute value
|
42
|
+
def empty_value(attribute)
|
43
|
+
if abstract? then
|
44
|
+
attr_md = attribute_metadata(attribute)
|
45
|
+
# the Java property type
|
46
|
+
jtype = attr_md.property_descriptor.property_type if JavaAttributeMetadata === attr_md
|
47
|
+
# A primitive is either a boolean or a number (String is not primitive).
|
48
|
+
if jtype and jtype.primitive? then
|
49
|
+
type.name == 'boolean' ? false : 0
|
50
|
+
end
|
51
|
+
else
|
52
|
+
# Since this class is not abstract, create a prototype instance on demand and make
|
53
|
+
# a copy of the initialized collection value from that instance.
|
54
|
+
@prototype ||= new
|
55
|
+
value = @prototype.send(attribute) || return
|
56
|
+
value.class.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
34
60
|
# Prints this classifier's content to the log.
|
35
61
|
def pretty_print(q)
|
62
|
+
|
63
|
+
|
64
|
+
# KLUDGE - if not inited then bail
|
65
|
+
if @attr_md_hash.nil? then
|
66
|
+
q.text(qp)
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
|
36
71
|
# the Java property descriptors
|
37
72
|
property_descriptors = java_attributes.wrap { |attr| attribute_metadata(attr).property_descriptor }
|
38
73
|
# build a map of relevant display label => attributes
|
@@ -71,16 +106,6 @@ module CaRuby
|
|
71
106
|
end
|
72
107
|
|
73
108
|
protected
|
74
|
-
|
75
|
-
# Adds the given subclass to this class's {ResourceMetadata#domain_module}.
|
76
|
-
def introspect_subclass(klass)
|
77
|
-
# introspect this class if necessary
|
78
|
-
unless @domain_module then
|
79
|
-
raise TypeError.new("Can't introspect #{qp}") unless superclass and superclass.include?(Resource)
|
80
|
-
superclass.introspect_subclass(self)
|
81
|
-
end
|
82
|
-
@domain_module.add_class(klass)
|
83
|
-
end
|
84
109
|
|
85
110
|
def self.extend_class(klass, mod)
|
86
111
|
klass.extend(self)
|
@@ -105,12 +130,9 @@ module CaRuby
|
|
105
130
|
|
106
131
|
def format_print_value(value)
|
107
132
|
case value
|
108
|
-
|
109
|
-
value
|
110
|
-
|
111
|
-
value.qp
|
112
|
-
else
|
113
|
-
value.pp_s(:single_line)
|
133
|
+
when String then value
|
134
|
+
when Class then value.qp
|
135
|
+
else value.pp_s(:single_line)
|
114
136
|
end
|
115
137
|
end
|
116
138
|
end
|
@@ -47,21 +47,23 @@ module CaRuby
|
|
47
47
|
module ResourceModule
|
48
48
|
# Adds the given klass to this ResourceModule. The class is extended with ResourceMetadata methods.
|
49
49
|
def add_class(klass)
|
50
|
-
@
|
50
|
+
@rsc_classes ||= Set.new
|
51
51
|
# add superclass if necessary
|
52
|
-
unless @
|
52
|
+
unless @rsc_classes.include?(klass.superclass) or klass.superclass == Java::JavaLang::Object then
|
53
53
|
# the domain module includes the superclass on demand
|
54
54
|
const_get(klass.superclass.name[/\w+$/].to_sym)
|
55
55
|
end
|
56
56
|
ResourceMetadata.extend_class(klass, self)
|
57
|
-
@
|
57
|
+
@rsc_classes << klass
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
61
|
-
def
|
62
|
-
@
|
60
|
+
# @return [Module] the resource mix-in module (default {Resouce})
|
61
|
+
def mixin
|
62
|
+
@mixin || Resource
|
63
63
|
end
|
64
64
|
|
65
|
+
# @return [{Symbol => Object}] the caBIG application access properties
|
66
|
+
# @see #load_access_properties
|
65
67
|
def access_properties
|
66
68
|
@resource_module__props ||= load_access_properties
|
67
69
|
end
|
@@ -70,9 +72,9 @@ module CaRuby
|
|
70
72
|
# The default file path is a period followed by the lower-case application name in the home directory,
|
71
73
|
# e.g. +~/.clincaltrials+.
|
72
74
|
#
|
73
|
-
# The property file format is a series of property definitions in the form _property_
|
75
|
+
# The property file format is a series of property definitions in the form _property_: _value_.
|
74
76
|
# The supported properties include the following:
|
75
|
-
# * +path+ - the application client Java
|
77
|
+
# * +path+ - the application client Java directories
|
76
78
|
# * +user+ - the application service login
|
77
79
|
# * +password+ - the application service password
|
78
80
|
# * +database+ - the application database name
|
@@ -82,8 +84,13 @@ module CaRuby
|
|
82
84
|
# * +database_type+ - the application database type, + mysql+ or +oracle+ (default +mysql+)
|
83
85
|
# * +database_driver+ - the application database connection driver (default is the database type default)
|
84
86
|
# * +database_port+ - the application database connection port
|
85
|
-
#
|
86
|
-
#
|
87
|
+
#
|
88
|
+
# The +path+ value is one or more directories separated by a semi-colon(;) or colon (:)
|
89
|
+
# Each path directory and all jar files within the directory are added to the caRuby execution
|
90
|
+
# Java classpath.
|
91
|
+
#
|
92
|
+
# @param [String, nil] file the property file, or nil for the default location
|
93
|
+
# @return [{Symbol => Object}] the loaded caBIG application access properties
|
87
94
|
def load_access_properties(file=nil)
|
88
95
|
# If a file was specified, then it must exist.
|
89
96
|
if file and not File.exists?(file) then
|
@@ -146,7 +153,7 @@ module CaRuby
|
|
146
153
|
sym = base_name.camelize.to_sym
|
147
154
|
sym_file_hash[sym] = file
|
148
155
|
autoload(sym, file)
|
149
|
-
|
156
|
+
end
|
150
157
|
|
151
158
|
# load the domain class definitions
|
152
159
|
sym_file_hash.each do |sym, file|
|
@@ -163,10 +170,29 @@ module CaRuby
|
|
163
170
|
end
|
164
171
|
|
165
172
|
# Extends the mod module with Java class support. See the class documentation for details.
|
173
|
+
#
|
174
|
+
# @param [Symbol] symbol the missing constant
|
166
175
|
def const_missing(symbol)
|
167
176
|
autoload?(symbol) ? super : import_domain_class(symbol)
|
168
177
|
end
|
169
178
|
|
179
|
+
# Returns the domain class for class_name, or nil if none in this module.
|
180
|
+
def domain_type_with_name(class_name)
|
181
|
+
pkg, base = split_class_name(class_name)
|
182
|
+
return unless pkg.nil? or pkg == @java_package
|
183
|
+
begin
|
184
|
+
type = const_get(base)
|
185
|
+
rescue JavaIncludeError
|
186
|
+
# no such domain type; not an error.
|
187
|
+
# other exceptions indicate that there was a domain type but could not be loaded; these exceptions propagate up the call stack
|
188
|
+
logger.debug("#{base} is not a #{qp} Java class.")
|
189
|
+
return
|
190
|
+
end
|
191
|
+
type if type < Resource
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
170
196
|
# Imports the domain Java class with specified class name_or_sym.
|
171
197
|
# This method enables the domain class extensions for storing and retrieving domain objects.
|
172
198
|
# The class is added to this module.
|
@@ -218,10 +244,10 @@ module CaRuby
|
|
218
244
|
# the Resource import stack
|
219
245
|
@import_stack ||= []
|
220
246
|
@import_stack.push klass
|
221
|
-
# include the Resource mixin
|
222
|
-
|
223
|
-
klass.instance_eval
|
224
|
-
|
247
|
+
# include the Resource mixin in the imported class
|
248
|
+
inc = "include #{mixin}"
|
249
|
+
klass.instance_eval(inc)
|
250
|
+
|
225
251
|
# if we are back to top of the stack, then print the imported Resources
|
226
252
|
if klass == @import_stack.first then
|
227
253
|
# a referenced class could be imported on demand in the course of printing a referencing class;
|
@@ -235,23 +261,6 @@ module CaRuby
|
|
235
261
|
klass
|
236
262
|
end
|
237
263
|
|
238
|
-
# Returns the domain class for class_name, or nil if none in this module.
|
239
|
-
def domain_type_with_name(class_name)
|
240
|
-
pkg, base = split_class_name(class_name)
|
241
|
-
return unless pkg.nil? or pkg == @java_package
|
242
|
-
begin
|
243
|
-
type = const_get(base)
|
244
|
-
rescue JavaIncludeError
|
245
|
-
# no such domain type; not an error.
|
246
|
-
# other exceptions indicate that there was a domain type but could not be loaded; these exceptions propagate up the call stack
|
247
|
-
logger.debug("#{base} is not a #{qp} Java class.")
|
248
|
-
return
|
249
|
-
end
|
250
|
-
type if type < Resource
|
251
|
-
end
|
252
|
-
|
253
|
-
private
|
254
|
-
|
255
264
|
# The property/value matcher, e.g.:
|
256
265
|
# host: jacardi
|
257
266
|
# host = jacardi
|
@@ -273,7 +282,7 @@ module CaRuby
|
|
273
282
|
end
|
274
283
|
end
|
275
284
|
|
276
|
-
#
|
285
|
+
# @return [(String, Symbol)] the [package prefix, base class symbol] pair
|
277
286
|
def split_class_name(class_name)
|
278
287
|
# the package prefix, including the period
|
279
288
|
package = Java.java_package_name(class_name)
|