Get class name of class - jenkins

Groovy beginner, coming from Java / Kotlin, how do I get the class name of an (anonymous) implementation of my class?
Failed attempts:
abstract class Foo {
String name() { this.class.simpleName }
}
abstract class Foo {
String name() { return this.class.simpleName }
}
abstract class Foo {
String name() { return getClass().getSimpleName() }
}
abstract class Foo {
String name() { this.metaClass.classNode.nameWithoutPackage }
}
So obviously I seem to give some class instance a default name. I thought "well, if class name does not work, let's try individual naming" with this:
abstract class Foo {
private final AtomicInteger counter = new AtomicInteger(0)
String name() { "number " + this.counter.incrementAndGet() }
}
but this doesn't work either because counter is not a property of groovy.lang.Binding.
This is all in context of a Jenkins pipeline I try to write... why is this so hard?

You probably want this...
abstract class Foo {
String name() { this.class.name }
}

Related

Dagger - Is it possible to select a Provider based on inheritance?

At the moment I have a Base class that contains a member I would like to inject. However, I would like the concrete type of this member to depend on the Subclass being instantiated. What I am aiming for is something along these lines:
public interface StringInterface {
public String getString();
}
public class HelloStringConcrete implements StringInterface {
public String getString() {
return "Hello";
}
}
public class WorldStringConcrete implements StringInterface {
public String getString() {
return "World";
}
}
public abstract class Base {
#Inject StringInterface member;
public Base() {
// Assume access to object graph
MyObjectGraph.get().inject(this);
}
public void printSomething() {
System.out.println(member.getString());
}
}
public class SubclassHello extends Base {}
public class SubclassWorld extends Base {}
#Module(injects = {SubclassHello.class})
public class HelloModule {
#Provides StringInterface provideStringInterface() {
return new HelloStringConcrete();
}
}
#Module(injects = {SubclassWorld.class})
public class WorldModule {
#Provides StringInterface provideStringInterface() {
return new WorldStringConcrete();
}
}
So now what I would like to do is something along the lines of:
#Module(
includes = {
HelloModule.class,
WorldModule.class
}
)
public class BigModule {}
// Somewhere in another piece of code...
objectGraph = ObjectGraph.create(new BigModule());
// In yet another piece of code...
SubclassHello hello = new SubclassHello();
SubclassWorld world = new SubclassWorld();
hello.printSomething();
world.printSomething();
// Hopefully would result in :
// Hello
// World
This type of setup won't work though, because including two modules with the same provider will result in a duplicate provider error at compile time. It would be cool to see a solution to this problem without introducing #Named or #Qualifer annotations, or using scoped graph extensions via graph.plus() because these strategies necessarily introduce coupling to the subclasses
This is possible but I think the code I've attached below is more coupled than using scoped graphs or annotations. Basically you can use constructor injection to inject concrete dependencies to your
SubclassHello and SubclassWorld.
public abstract class Base {
private final StringInterface member;
public Base(StringInterface member) {
this.member = member;
}
...
}
#Module(injects = {SubclassWorld.class})
public class WorldModule {
#Provides
WorldStringConcrete provideStringInterface() {
return new WorldStringConcrete();
}
}
public class SubclassWorld extends Base {
#Inject
public SubclassWorld(WorldStringConcrete worldStringConcrete) {
super(worldStringConcrete);
}
}
#Module(injects = {SubclassHello.class})
public class HelloModule {
#Provides
HelloStringConcrete provideStringInterface() {
return new HelloStringConcrete();
}
}
public class SubclassHello extends Base {
#Inject
public SubclassHello(HelloStringConcrete helloStringConcrete) {
super(helloStringConcrete);
}
}
// Somewhere in another piece of code...
ObjectGraph objectGraph = ObjectGraph.create(new BigModule());
// In yet another piece of code...
SubclassHello hello = objectGraph.get(SubclassHello.class);
SubclassWorld world = objectGraph.get(SubclassWorld.class);
I don't think there are other solutions. How could Dagger find out which StringInterface implementations should be injected to the concrete classes?

Struts 2 get custom action anotation in interceptors

Consider below action class with three action mappings. Two of them are annotated with a custom annotation #AjaxAction
public class MyAction extends ActionSupport{
#Action("action1")
#AjaxAction //My custom anotation
public String action1(){
}
#Action("action2")
public String action2(){
}
#Action("action3")
#AjaxAction //My custom anotation
public String action3(){
}
}
In an interceptor I want to access the #AjaxAction annotation. Is there any built in support for this?!
If not can I shall read the action name with ActionContext.getContext().getName(); and save a list of ajaxAction names in interceptor as an array and compare action name with this array! any better way?!
private static final String[] AJAX_ACTIONS = new String[] {"action1", "action3"}
//in interceptor
String actionName = ActionContext.getContext().getName();
if (Arrays.asList(AJAX_ACTIONS).contains(actionName)) {
// do something
}
Here is the way
import java.lang.reflect.Method;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class YourInterceptor implements Interceptor {
#Override
public String intercept(ActionInvocation inv) throws Exception {
Class myActionClass = inv.getAction().getClass();
for (Method method : myActionClass.getMethods())
{
if(method.isAnnotationPresent(AjaxAction.class))
{
// do something
}
}
return inv.invoke();
}
}
Alternative is
import com.opensymphony.xwork2.util.AnnotationUtils;
import java.lang.reflect.Method;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class YourInterceptor implements Interceptor {
#Override
public String intercept(ActionInvocation inv) throws Exception {
AnnotationUtils myutil = new AnnotationUtils();
Class myActionClass = inv.getAction().getClass();
for (Method method : myActionClass.getMethods())
{
if(myutil.getAnnotatedMethods(myActionClass, AjaxAction.class).contains(method))
{
// do something
}
}
return inv.invoke();
}
}
Edit :
To find exact executed method.
Note: Change Namespace="/" as per your configuration in struts.xml.
import org.apache.struts2.dispatcher.Dispatcher;
ActionContext context = inv.getInvocationContext();
String executedAction=context.getName();
String executedMethod=Dispatcher.getInstance().getConfigurationManager().getConfiguration().getRuntimeConfiguration().getActionConfigs().get("/").get(executedAction).getMethodName();
if(executedMethod==null)
{
executedMethod="execute";
}
for (Method method : myActionClass.getMethods())
{
if(method.getName().equalsIgnoreCase(executedMethod) || method.isAnnotationPresent(Action.class))
{
// do something
}
}
Class myActionClass = inv.getAction().getClass();
for (Method method : myActionClass.getMethods())
{
//check whether called method has annotation?
if(method.getName().equalsIgnoreCase(executedAction) && method.isAnnotationPresent(AjaxAction.class))
{
// do something
}
}
I hope this will work.
Note: This is just a workaround I found. Better way would be possible....

How to get the target class of a groovy mixin?

I'm trying to do the following in Grails:
class I18nEnum implements MessageSourceResolvable {
public Object[] getArguments() { [] as Object[] }
public String[] getCodes() { [ this.class.canonicalName+'.'+name() ] }
public String getDefaultMessage() { "?-" + name() }
}
and then use this class like this:
class MyDomainClass {
#Mixin(I18nEnum)
public static enum MaritalStatus {
SINGLE, MARRIED
}
MaritalStatus maritalStatus
}
Then MyDomainClass is used with scaffolding to generate an HTML select field, and to have the options translatable in messages.properties like this:
my.package.MyDomainClass.MaritalStatus.SINGLE = Single
my.package.MyDomainClass.MaritalStatus.MARRIED = Married
But I cannot find a way to get the name of the target class (my.package.MyDomainClass.MaritalStatus), and instead I get the name of the mixin class (my.package.I18nEnum#1dd658e9)
How can I get the target class of a groovy mixin?
Is there a way to do something like this?
public String[] getCodes() { [ this.targetClass.canonicalName+'.'+name() ] }
Or like this?
public String[] getCodes() { [ this.mixinTargetClass.canonicalName+'.'+name() ] }
Note: For the moment the only way that I made this enum internationalization feature to work was by just copy-pasting this for every enum class defined in the application:
public static enum MaritalStatus implements MessageSourceResolvable {
SINGLE, MARRIED
public Object[] getArguments() { [] as Object[] }
public String[] getCodes() { [ this.class.canonicalName+'.'+name() ] }
public String getDefaultMessage() { name() }
}
MaritalStatus maritalStatus
But I would like to not repeat the same code for every enum, but instead just mixin the required methods implementing MessageSourceResolvable.
Mixins do not work with enums. May be it will be useful for you:
class Mix {
def enumClazz
Mix(def clz) { enumClazz = clz }
def getCode() { println "---> ${enumClazz.name()}"}
}
enum MaritalStatus {
SINGLE, MARRIED
#Delegate Mix mixClz = new Mix(this)
}
MaritalStatus.MARRIED.code

Cannot invoke method render() on null object in Grail while email sending

I am using mail:1.0.1 plugin for mail sending
but while sending mail its gives me an error..
Source :-
def serviceMethod(EmailModel mailObj) {
PageRenderer groovyPageRenderer;
try{
sendMail {
to "abc#gmail.com"
subject mailObj.subject;
html groovyPageRenderer.render(template:"myMailTemplate", model: [mailObj: mailObj])
}
} catch (Throwable th) {
th.printStackTrace();
}
}
If you want to send the gsp page as email body then you can send it like:
def mailService
def serviceMethod(EmailModel mailObj) {
...
mailService.sendMail {
to email
subject "subject"
body(view: "/_template", model: [mailObj: mailObj])
}
...
}
EDIT...................................................................................
Just inject PageRenderer groovyPageRenderer globally, like
import grails.gsp.PageRenderer
class TestService {
PageRenderer groovyPageRenderer
def getText() {
String s = groovyPageRenderer.render(template: "../first/temp", model: [name: 'user1690588'])
println "Content = ${s}"
}
}
I think you are calling Service Class(.groovy) method from java class.
by using object of EmailService class.
So you cant get Object of PageRenderer class.
for this
Create SpringsUtil Class in src/java and define constant object of EmailSerevice. like this
public class SpringsUtil {
public static ApplicationContext getCtx() {
return getApplicationContext();
}
public static ApplicationContext getApplicationContext() {
return (ApplicationContext) ServletContextHolder.getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT);
}
#SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
return (T) getApplicationContext().getBean(beanName);
}
public static final String EMAIL_SERVICE = "emailService";
// public static final String INVENTORY_REORDER_SERVICE = "InventoryReorderService";
}
create object of Service class and call method
EmailService emailService = SpringsUtil.getBean(SpringsUtil.EMAIL_SERVICE);

How can refer base class instance?

The following example, how do I refer base class instance?
public class A
{
public string test;
public A()
{
B b = new B();
test = "I am A class of test.";
}
public void hello()
{
MessageBox.Show("I am A class of hello.");
}
class B
{
public B()
{
//Here...
//How can I get A class of test and call A class of hello method
//base.test or base.hello() are not working.
}
}
}
You'd have to pass a reference of A to B.
One way you can do this is as follows:
public class A
{
string name = "Class A";
public A()
{
var b = new B(this);
}
class B
{
public B(A a)
{
a.name.Dump(); // Write out the property of a.name to some stream.
}
}
}
To clearly distinguish between base class and nested class, please refer the example below.
namespace Example
{
class A
{
string Name = "test"; // access restricted only to this class
public string Type; // global access
internal string Access; // within defining namespace
protected string Code; // this class and subclass
// When you create a nested class like C, you can create instances of C within this class(A).
C c = new C();
class C
{
string name;
public C()
{
//this is a nested class and you cannot call A as its base
name = "test success";
}
}
}
class B : A
{
public string Type { get { return base.Type; } set { base.Type = value; } } // You can use base when you hide a base class member
public B()
{
Type = "test";
Code = "nothing";
Access = "success";
//Cannot Access 'Name' Here as it is private
}
}
}

Resources