Information about a field, as read from a class file.
A ClassFinder
finds classes in a class path, returning the result in a
lazy iterator.
A ClassFinder
finds classes in a class path, returning the result in a
lazy iterator. The iterator can then be filtered, mapped, or passed to
the utility methods in the ClassFinder
companion object.
Information about a class, as read from a class file.
Information about a field, as read from a class file.
Takes a Scala Map
, with String
keys and object values, and generates
an object, with fields for each map value.
Takes a Scala Map
, with String
keys and object values, and generates
an object, with fields for each map value. Field that are, themselves,
Map[String,Any]
objects can be recursively mapped, as well.
Information about a method, as read from a class file.
The entrance to the factory floor, providing methods for finding and filtering classes.
Some general-purpose class-related utility functions.
Takes a Scala Map
, with String
keys and object values, and generates
a Java Bean object, with fields for each map value.
Takes a Scala Map
, with String
keys and object values, and generates
a Java Bean object, with fields for each map value. Field that are,
themselves, Map[String,Any]
objects can be recursively mapped, as
well. The map's keys are mapped to Java Bean get
accessors. For
instance, a key name "foo" is mapped to a method called getFoo()
.
The transformation results in an object that can only really be used via reflection; however, that fits fine with some APIs that want to receive Java Beans as parameters.
There are some restrictions imposed on any map that is to be converted.
- Only maps with string keys can be converted. - The string keys must be valid Java identifiers.
Here's a simple example:
import org.clapper.classutil._ val charList = List('1', '2', '3') val subMap = Map("sub1" -> 1, "sub2" -> 2) val m = Map("oneInt" -> 1, "twoFloat" -> 2f, "threeString" -> "three", "fourIntClass" -> classOf[Int], "fiveMap" -> subMap, "sixList" -> charList) val obj = MapToBean(m) def showName(name: String) = (name startsWith "get") obj.getClass.getMethods.filter(m => showName(m.getName)).foreach(println _) def call(methodName: String) = { val method = obj.getClass.getMethod(methodName) method.invoke(obj) } println println("getFiveMap returns " + call("getFiveMap"))
That Scala script will produce output like the following:
public final $Proxy0 $Proxy1.getFiveMap() public final java.lang.Integer $Proxy1.getOneInt() public final java.lang.Class $Proxy1.getFourIntClass() public final scala.collection.immutable.$colon$colon $Proxy1.getSixList() public final java.lang.Float $Proxy1.getTwoFloat() public final java.lang.String $Proxy1.getThreeString() public static java.lang.Class java.lang.reflect.Proxy.getProxyClass(java.lang.ClassLoader,java.lang.Class[]) throws java.lang.IllegalArgumentException public static java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.getInvocationHandler(java.lang.Object) throws java.lang.IllegalArgumentException public final native java.lang.Class java.lang.Object.getClass() getFiveMap returns Map(getSub1 -> 1, getSub2 -> 2)
An enumerated high-level view of the modifiers that can be attached to a method, class or field.
ScalaObjectToBean
maps a Scala object into a read-only Java bean.
ScalaObjectToBean
maps a Scala object into a read-only Java bean. It
takes a Scala object, locates the Scala accessors (using simple
heuristics), and generates a new object with additional Java Bean get
and set
methods for the accessors. ScalaObjectToBean
is an
alternative to using the @BeanProperty
annotation on classes, so it is
useful for mapping case classes into Java Beans, or for mapping classes
from other APIs into Java Beans without having to extend them.
ScalaObjectToBean
uses the following heuristics to determine which fields
to map.
First, it recognizes that any Scala val
or var
is really a getter method
returning some type. That is:
val x: Int = 0 var y: Int = 10
is compiled down to the equivalent of the following Java code:
private int _x = 0; private int _y = 10; public int x() { return _x; } public int y() { return _y; } public void y_$eq(int newY) { _y = newY; }
So, the mapper looks for Scala getter methods that take no parameters
and return some non-void (i.e., non-Unit
) value, and it looks for
Scala setter methods that take one parameter, return void (Unit
) and
have names ending in "_$eq". Then, from that set of methods, the mapper
discards:
- Methods starting with "get"
- Methods that have a corresponding "get" method. In the above example,
if there's a getX()
method that returns an int
, the mapper will
assume that it's the bean version of x()
, and it will ignore x()
.
- Methods that aren't public.
- Any method in java.lang.Object
.
- Any method in scala.Product
.
If there are any methods in the remaining set, then the mapper returns a new wrapper object that contains Java Bean versions of those methods; otherwise, the mapper returns the original Scala object. The resulting bean delegates its calls to the original object, instead of capturing the object's method values at the time the bean is called. That way, if the underlying Scala object's methods return different values for each call, the bean will reflect those changes.
Classes and utilities for operating on JVM classes, at runtime.