BAEL-2781 - metaprogramming in groovy
This commit is contained in:
parent
66c91e7295
commit
a49bd1ad2b
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.metaprogramming
|
||||||
|
|
||||||
|
import groovy.transform.AutoClone
|
||||||
|
import groovy.transform.Canonical
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.ToString
|
||||||
|
import groovy.transform.TupleConstructor
|
||||||
|
import groovy.util.logging.*
|
||||||
|
|
||||||
|
@Canonical
|
||||||
|
@TupleConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString(includePackage=false, excludes=['id'])
|
||||||
|
//@Singleton
|
||||||
|
@Log
|
||||||
|
@AutoClone
|
||||||
|
class Employee {
|
||||||
|
|
||||||
|
long id
|
||||||
|
String firstName
|
||||||
|
String lastName
|
||||||
|
int age
|
||||||
|
|
||||||
|
//method to catch missing property's getter
|
||||||
|
def propertyMissing(String propertyName) {
|
||||||
|
log.info "$propertyName is not available"
|
||||||
|
"property '$propertyName' is not available"
|
||||||
|
}
|
||||||
|
|
||||||
|
//method to catch missing property's setter
|
||||||
|
def propertyMissing(String propertyName, propertyValue) {
|
||||||
|
println "property '$propertyName' is not available"
|
||||||
|
log.info "$propertyName is not available"
|
||||||
|
"property '$propertyName' is not available"
|
||||||
|
}
|
||||||
|
|
||||||
|
def methodMissing(String methodName, def methodArgs) {
|
||||||
|
log.info "$methodName is not defined"
|
||||||
|
"method '$methodName' is not defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.metaprogramming.extension
|
||||||
|
|
||||||
|
import com.baeldung.metaprogramming.Employee
|
||||||
|
|
||||||
|
class BasicExtensions {
|
||||||
|
|
||||||
|
static int getYearOfBirth(Employee self) {
|
||||||
|
return (new Date().getYear() + 1900) - self.age;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String capitalize(String self) {
|
||||||
|
return self.substring(0, 1).toUpperCase() + self.substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printCounter(Integer self) {
|
||||||
|
while (self>0) {
|
||||||
|
println self
|
||||||
|
self--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Long square(Long self) {
|
||||||
|
return self*self
|
||||||
|
}
|
||||||
|
|
||||||
|
static BigDecimal cube(BigDecimal self) {
|
||||||
|
return self*self*self
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.baeldung.metaprogramming.extension
|
||||||
|
|
||||||
|
import com.baeldung.metaprogramming.Employee
|
||||||
|
|
||||||
|
class StaticEmployeeExtension {
|
||||||
|
|
||||||
|
static Employee getDefaultObj(Employee self) {
|
||||||
|
return new Employee(firstName: "firstName", lastName: "lastName", age: 20)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
moduleName=core-groovy-2
|
||||||
|
moduleVersion=1.0-SNAPSHOT
|
||||||
|
extensionClasses=com.baeldung.metaprogramming.extension.BasicExtensions
|
||||||
|
staticExtensionClasses=com.baeldung.metaprogramming.extension.StaticEmployeeExtension
|
|
@ -0,0 +1,115 @@
|
||||||
|
package com.baeldung.metaprogramming
|
||||||
|
|
||||||
|
import groovy.time.TimeCategory
|
||||||
|
|
||||||
|
class MetaprogrammingUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
Employee emp = new Employee(firstName: "Norman", lastName: "Lewis")
|
||||||
|
|
||||||
|
void testPropertyMissing() {
|
||||||
|
assert emp.address == "property 'address' is not available"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMethodMissing() {
|
||||||
|
Employee emp = new Employee()
|
||||||
|
try {
|
||||||
|
emp.getFullName()
|
||||||
|
} catch(MissingMethodException e) {
|
||||||
|
println "method is not defined"
|
||||||
|
}
|
||||||
|
assert emp.getFullName() == "method 'getFullName' is not defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMetaClassProperty() {
|
||||||
|
Employee.metaClass.address = ""
|
||||||
|
emp = new Employee(firstName: "Norman", lastName: "Lewis", address: "US")
|
||||||
|
assert emp.address == "US"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMetaClassMethod() {
|
||||||
|
emp.metaClass.getFullName = {
|
||||||
|
"$lastName, $firstName"
|
||||||
|
}
|
||||||
|
assert emp.getFullName() == "Lewis, Norman"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMetaClassConstructor() {
|
||||||
|
try {
|
||||||
|
Employee emp = new Employee("Norman")
|
||||||
|
} catch(GroovyRuntimeException e) {
|
||||||
|
assert e.message == "Could not find matching constructor for: com.baeldung.metaprogramming.Employee(String)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Employee.metaClass.constructor = { String firstName ->
|
||||||
|
new Employee(firstName: firstName)
|
||||||
|
}
|
||||||
|
|
||||||
|
Employee norman = new Employee("Norman")
|
||||||
|
assert norman.firstName == "Norman"
|
||||||
|
assert norman.lastName == null
|
||||||
|
}
|
||||||
|
|
||||||
|
void testJavaMetaClass() {
|
||||||
|
String.metaClass.capitalize = { String str ->
|
||||||
|
str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||||
|
}
|
||||||
|
assert "norman".capitalize() == "Norman"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testEmployeeExtension() {
|
||||||
|
Employee emp = new Employee(age: 28)
|
||||||
|
assert emp.getYearOfBirth() == 1991
|
||||||
|
}
|
||||||
|
|
||||||
|
void testJavaClassesExtensions() {
|
||||||
|
5.printCounter()
|
||||||
|
|
||||||
|
assert 40l.square() == 1600l
|
||||||
|
|
||||||
|
assert (2.98).cube() == 26.463592
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStaticEmployeeExtension() {
|
||||||
|
assert Employee.getDefaultObj().firstName == "firstName"
|
||||||
|
assert Employee.getDefaultObj().lastName == "lastName"
|
||||||
|
assert Employee.getDefaultObj().age == 20
|
||||||
|
}
|
||||||
|
|
||||||
|
void testToStringAnnotation() {
|
||||||
|
Employee employee = new Employee()
|
||||||
|
employee.id = 1
|
||||||
|
employee.firstName = "norman"
|
||||||
|
employee.lastName = "lewis"
|
||||||
|
employee.age = 28
|
||||||
|
|
||||||
|
assert employee.toString() == "Employee(norman, lewis, 28)"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testTupleConstructorAnnotation() {
|
||||||
|
Employee norman = new Employee(1, "norman", "lewis", 28)
|
||||||
|
assert norman.toString() == "Employee(norman, lewis, 28)"
|
||||||
|
|
||||||
|
Employee snape = new Employee(2, "snape")
|
||||||
|
assert snape.toString() == "Employee(snape, null, 0)"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testEqualsAndHashCodeAnnotation() {
|
||||||
|
Employee norman = new Employee(1, "norman", "lewis", 28)
|
||||||
|
Employee normanCopy = new Employee(1, "norman", "lewis", 28)
|
||||||
|
assert norman == normanCopy
|
||||||
|
assert norman.hashCode() == normanCopy.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
void testAutoCloneAnnotation() {
|
||||||
|
try {
|
||||||
|
Employee norman = new Employee(1, "norman", "lewis", 28)
|
||||||
|
def normanCopy = norman.clone()
|
||||||
|
assert norman == normanCopy
|
||||||
|
} catch(CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue