Class: Module
- Defined in:
- lib/jinx/import/java.rb,
lib/jinx/helpers/module.rb,
lib/jinx/helpers/pretty_print.rb
Constant Summary collapse
- OBJ_INST_MTHDS =
Object.instance_methods
Class Method Summary collapse
-
.to_ruby(mod) ⇒ Module
Returns the Ruby module for the given argument, as follows: * If the argument is a primitive Java type, then return the corresponding JRuby wrapper.
Instance Method Summary collapse
-
#abstract? ⇒ Boolean
Whether this is a wrapper for an abstract Java class.
-
#java_class? ⇒ Boolean
Returns whether this is a Ruby wrapper for a Java class or interface.
-
#module_with_name(name) ⇒ Module?
Returns the class or module with the given name defined in this module.
-
#parent_module ⇒ Module
This module’s definition context.
-
#property_descriptors(hierarchy = true) ⇒ Object
Returns this class’s readable and writable Java PropertyDescriptors, or an empty Array if none.
-
#property_read_method(pd) ⇒ Symbol
The property descriptor pd introspected or discovered Java read Method.
-
#qp ⇒ String
The demodulized name.
-
#transient?(pd) ⇒ Boolean
Returns whether the given PropertyDescriptor pd corresponds to a transient field in this class, or nil if there is no such field.
-
#unocclude_reserved_method(pd) ⇒ Object
Redefines the reserved method corresponding to the given Java property descriptor back to the Object implementation, if necessary.
Class Method Details
.to_ruby(mod) ⇒ Module
Returns the Ruby module for the given argument, as follows:
-
If the argument is a primitive Java type, then return the corresponding JRuby wrapper.
-
If the argument is a Ruby module, then return that module.
-
If the argument is an unwrapped Java class or interface, then return the JRuby wrapper for the class string.
-
If the argument is a String, then return the JRuby wrapper for the Java class designated by that String.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/jinx/import/java.rb', line 226 def self.to_ruby(mod) if mod.respond_to?(:java_class) then # A primitive Java type has an empty name and non-capitalized java_class name. jname = mod.name.blank? ? mod.java_class.name : mod.name if jname.blank? then raise ArgumentError.new("Cannot convert the anonymous Java class #{mod} to a JRuby class") end if jname =~ /^[a-z]+$/ then # The effective Java type is the Java wrapper class. to_ruby('java.lang.' + jname.capitalize) elsif Module === mod then mod else to_ruby(jname) end elsif Module === mod then mod elsif String === mod then eval "Java::#{mod}" else raise ArgumentError.new("Cannot convert a #{mod.class} to a JRuby module") end end |
Instance Method Details
#abstract? ⇒ Boolean
Returns whether this is a wrapper for an abstract Java class.
251 252 253 |
# File 'lib/jinx/import/java.rb', line 251 def abstract? java_class? and Java::JavaLangReflect::Modifier.isAbstract(java_class.modifiers) end |
#java_class? ⇒ Boolean
Returns whether this is a Ruby wrapper for a Java class or interface.
206 207 208 |
# File 'lib/jinx/import/java.rb', line 206 def java_class? respond_to?(:java_class) end |
#module_with_name(name) ⇒ Module?
Returns the class or module with the given name defined in this module. The name can qualified by parent modules, e.g. MyApp::Person
. If name cannot be resolved as a Module, then this method returns nil.
8 9 10 |
# File 'lib/jinx/helpers/module.rb', line 8 def module_with_name(name) name.split('::').inject(self) { |parent, part| parent.const_get(part) } rescue nil end |
#parent_module ⇒ Module
Returns this module’s definition context.
15 16 17 |
# File 'lib/jinx/helpers/module.rb', line 15 def parent_module module_with_name(name.split('::')[0..-2].join('::')) end |
#property_descriptors(hierarchy = true) ⇒ Object
Returns this class’s readable and writable Java PropertyDescriptors, or an empty Array if none. If the hierarchy flag is set to false
, then only this class’s properties will be introspected.
269 270 271 272 273 |
# File 'lib/jinx/import/java.rb', line 269 def property_descriptors(hierarchy=true) return Array::EMPTY_ARRAY unless java_class? info = hierarchy ? Java::JavaBeans::Introspector.getBeanInfo(java_class) : Java::JavaBeans::Introspector.getBeanInfo(java_class, java_class.superclass) info.propertyDescriptors.select { |pd| pd.write_method and property_read_method(pd) } end |
#property_read_method(pd) ⇒ Symbol
Returns the property descriptor pd introspected or discovered Java read Method.
331 332 333 334 335 336 337 |
# File 'lib/jinx/import/java.rb', line 331 def property_read_method(pd) return pd.read_method if pd.read_method return unless pd.get_property_type == Java::JavaLang::Boolean.java_class rdr = java_class.java_method("is#{pd.name.capitalize_first}") rescue nil logger.debug { "Discovered #{qp} #{pd.name} property non-introspected reader method #{rdr.name}." } if rdr rdr end |
#qp ⇒ String
Returns the demodulized name.
106 107 108 |
# File 'lib/jinx/helpers/pretty_print.rb', line 106 def qp name[/\w+$/] end |
#transient?(pd) ⇒ Boolean
Returns whether the given PropertyDescriptor pd corresponds to a transient field in this class, or nil if there is no such field.
256 257 258 259 260 261 262 263 264 |
# File 'lib/jinx/import/java.rb', line 256 def transient?(pd) begin field = java_class.declared_field(pd.name) rescue Exception # should occur only if a property is not a field; not an error return end Java::JavaLangReflect::Modifier.isTransient(field.modifiers) if field end |
#unocclude_reserved_method(pd) ⇒ Object
Redefines the reserved method corresponding to the given Java property descriptor back to the Object implementation, if necessary. If both this class and Object define a method with the given property name, then a new method is defined with the same body as the previous method. Returns the new method symbol, or nil if the property name is not an occluded Object instance method.
This method undoes the JRuby clobbering of Object methods by Java property method wrappers. The method is renamed as follows:
-
id
is changed to :identifier -
type
is prefixed by the underscore subject class name, e.g. Specimen.type => :specimen_type, If the property name istype
and the subject class name ends in ‘Type’, then the property symbol is the underscore subject class name, e.g. HistologicType.type => :histologic_type.
Raises ArgumentError if symbol is not an Object method.
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/jinx/import/java.rb', line 290 def unocclude_reserved_method(pd) oldname = pd.name.underscore return unless OBJ_INST_MTHDS.include?(oldname) oldsym = oldname.to_sym undeprecated = case oldsym when :id then :object_id when :type then :class else oldsym end rsvd_mth = Object.instance_method(undeprecated) base = self.qp.underscore newname = if oldname == 'id' then 'identifier' elsif base[-oldname.length..-1] == oldname then base else "#{base}_#{oldname}" end newsym = newname.to_sym rdr = property_read_method(pd).name.to_sym alias_method(newsym, rdr) # alias the writers wtr = pd.write_method.name.to_sym alias_method("#{newsym}=".to_sym, wtr) # alias a camel-case Java-style method if necessary altname = newname.camelize unless altname == newname then alias_method(altname.to_sym, oldsym) alias_method("#{altname}=".to_sym, wtr) end # restore the old method to Object define_method(oldsym) { |*args| rsvd_mth.bind(self).call(*args) } newsym end |