Groovy Inner Classes wont work with Apache Wicket - groovy

Im trying to write simple things with Apache Wicket (6.15.0) and Groovy (2.2.2 or 2.3.1). And Im having trouble with inner classes.
class CreatePaymentPanel extends Panel {
public CreatePaymentPanel(String id) {
super(id)
add(new PaymentSelectFragment('currentPanel').setOutputMarkupId(true))
}
public class PaymentSelectFragment extends Fragment {
public PaymentSelectFragment(String id) {
super(id, 'selectFragment', CreatePaymentPanel.this) // problem here
add(new AjaxLink('cardButton') {
#Override
void onClick(AjaxRequestTarget target) {
... CreatePaymentPanel.this // not accessible here
}
})
add(new AjaxLink('terminalButton') {
#Override
void onClick(AjaxRequestTarget target) {
... CreatePaymentPanel.this // not accessible here
}
});
}
} // end of PaymentSelectFragment class
} // end of CreatePaymentPanel class
Groovy tries to find a property "this" in CreatePaymentPanel class.. How to workaround this? It is a valid java code, but not groovy.
However,
Test.groovy:
class Test {
static void main(String[] args) {
def a = new A()
}
static class A {
A() {
def c = new C()
}
public void sayA() { println 'saying A' }
class B {
public B(A instance) {
A.this.sayA()
instance.sayA()
}
}
/**
* The problem occurs here
*/
class C extends B {
public C() {
super(A.this) // groovy tries to find property "this" in A class
sayA()
}
}
}
}
Above code wont work, the same error occurs, like in Wicket's case.
And TestJava.java, the same and working:
public class TestJava {
public static void main(String[] args) {
A a = new A();
}
static class A {
A() {
C c = new C();
}
public void sayA() {
System.out.println("saying A");
}
class B {
public B(A instance) {
instance.sayA();
}
}
/**
* This works fine
*/
class C extends B {
public C() {
super(A.this);
sayA();
}
}
}
}
What I am missing?

You can't refer to a CreatePaymentPanel.this inside of PaymentSelectFragment because there is no instance of CreatePamentPanel that would be accessible there. What would you expect that to evaluate to if it were allowed?

Related

Groovy $getCallSiteArray implementation

I am using groovy 2.4.12 with Oracle JVM 1.8. I am trying to understand a bit how groovyc converts the scripts written by end users.
To that end I wrote this simple script:
println 'Hello World`
This was compiled to bytecode using groovyc hello.groovy. Finally, I decompiled the hello.class to get the following code:
import groovy.lang.Binding;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class hello extends Script {
public hello() {
CallSite[] var1 = $getCallSiteArray();
}
public hello(Binding context) {
CallSite[] var2 = $getCallSiteArray();
super(context);
}
public static void main(String... args) {
CallSite[] var1 = $getCallSiteArray();
var1[0].call(InvokerHelper.class, hello.class, args);
}
public Object run() {
CallSite[] var1 = $getCallSiteArray();
return var1[1].callCurrent(this, "Hello World");
}
}
This looks like a typical Java class except I cannot figure out where $getCallSiteArray() method is defined. It is definitely not in this class and neither is it a public or protected member of groovy.lang.Script. So my question is where is this method implemented?
use another decompiler to see it
//
// Decompiled by Procyon v0.5.36
//
public class A extends Script
{
private static /* synthetic */ SoftReference $callSiteArray;
public A() {
$getCallSiteArray();
}
public A(final Binding context) {
$getCallSiteArray();
super(context);
}
public static void main(final String... args) {
$getCallSiteArray()[0].call((Object)InvokerHelper.class, (Object)A.class, (Object)args);
}
public Object run() {
return $getCallSiteArray()[1].callCurrent((GroovyObject)this, (Object)"hello world");
}
private static /* synthetic */ CallSiteArray $createCallSiteArray() {
final String[] array = new String[2];
$createCallSiteArray_1(array);
return new CallSiteArray((Class)A.class, array);
}
private static /* synthetic */ CallSite[] $getCallSiteArray() {
CallSiteArray $createCallSiteArray;
if (A.$callSiteArray == null || ($createCallSiteArray = A.$callSiteArray.get()) == null) {
$createCallSiteArray = $createCallSiteArray();
A.$callSiteArray = new SoftReference($createCallSiteArray);
}
return $createCallSiteArray.array;
}
}

Is threre any way to ues override method in anonymous class on Groovy #CompileStatic annotation

Is threre any way to ues override method in anonymous class on Groovy #CompileStatic annotation?
groogy source
import groovy.transform.CompileStatic;
interface HelloWorld {
public void greet();
}
class HelloWorldAnonymousClassesParents {
public void hi() {
println "hi"
}
}
#CompileStatic
public class HelloWorldAnonymousClasses extends HelloWorldAnonymousClassesParents {
public void hi() {
System.out.println("hihi ");
}
public void sayHello() {
HelloWorld spanishGreeting = new HelloWorld() {
public void greet() {
hi() //<- here [Static type checking] - Reference to method is ambiguous error
System.out.println("spanishGreeting");
}
};
spanishGreeting.greet();
hi()
}
}
def myApp = new HelloWorldAnonymousClasses();
myApp.sayHello();
Same source in java run well
java source
package org.octopus;
class HelloWorldAnonymousClassesParents {
public void hi() {
System.out.println("hi ");
}
}
interface HelloWorld {
public void greet();
}
public class Test extends HelloWorldAnonymousClassesParents{
public void hi() {
System.out.println("hihi ");
}
public void sayHello() {
HelloWorld spanishGreeting = new HelloWorld() {
public void greet() {
hi();
System.out.println("spanishGreeting");
}
};
spanishGreeting.greet();
hi();
}
public static void main(String... args) {
Test myApp = new Test();
myApp.sayHello();
}
}
How can I avoid that error with #CompileStatic annotation?
You can write it as a closure. This implies an as HelloWorld and as the interface only has one method groovy can deduct this.
HelloWorld spanishGreeting = {
hi()
System.out.println("spanishGreeting");
}
above code is groovy 2.3; with earlier groovy 2 versions it needs an explicit cast like
def spanishGreeting = {/*...*/} as HelloWorld

How to reuse method by passing different class object to the same method?

How to reuse method by passing different class object? I have 2 different classes, ClassOne and ClassTwo, in the method ProcessMessage I want to pass the Class also, but how?
Like this in someway //ProcessMessage(classText, objectTwo);
class ClassOne
{
public string MethodOne()
{
return ("ClassOne");
}
}
class ClassTwo
{
public string MethodOne()
{
return ("ClassTwo");
}
}
class Program
{
static void Main()
{
var objectOne = new ClassOne();
var classText = objectOne.MethodOne();
ProcessMessage(classText, objectOne);
var objectTwo = new ClassTwo();
classText = objectTwo.MethodOne();
//ProcessMessage(classText, objectTwo);
Console.ReadKey();
}
public static void ProcessMessage(string classText, ClassOne testClass)
{
Console.WriteLine("ClassText:{0}", classText);
}
}
If I use this(after getting help from you guys), I recognise know, how can I use testClass?
Like: var text= testClass.MethodOne(); or something
public static void ProcessMessage(string classText, ClassOne testClass)
{
Console.WriteLine("ClassText:{0}", classText);
}
I'm not sure why you want this since you are not using the testClass parameter in ProcessMessage anywhere.But you can use a generic method to pass any type of class to your method:
public static void ProcessMessage<T>(string classText, T testClass)
where T : class
{
Console.WriteLine("ClassText:{0}", classText);
}
Another alternative is creating a common interface or a base class for ClassOne and ClassTwo.And change the method:
public static void ProcessMessage(string classText, CommonInterface testClass)
{
Console.WriteLine("ClassText:{0}", classText);
}
It is possible to use Generics, but Like Prerak K said, why?
class ClassOne
{
public string MethodOne()
{
return ("ClassOne");
}
}
class ClassTwo
{
public string MethodOne()
{
return ("ClassTwo");
}
}
class Program
{
static void Main()
{
var objectOne = new ClassOne();
var classText = objectOne.MethodOne();
ProcessMessage(classText, objectOne);
var objectTwo = new ClassTwo();
classText = objectTwo.MethodOne();
ProcessMessage(classText, objectTwo);
Console.ReadKey();
}
public static void ProcessMessage<T>(string classText, T testClass)
{
Console.WriteLine("ClassText:{0}", classText);
}
}
Or you can create an interface like this:
interface IProcessable {
string MethodOne();
}
class ClassOne : IProcessable
{
public string MethodOne()
{
return ("ClassOne");
}
}
class ClassTwo : IProcessable
{
public string MethodOne()
{
return ("ClassTwo");
}
}
class Program
{
static void Main()
{
IProcessable objectOne = new ClassOne();
var classText = objectOne.MethodOne();
ProcessMessage(classText, objectOne);
IProcessable objectTwo = new ClassTwo();
classText = objectTwo.MethodOne();
ProcessMessage(classText, objectTwo);
Console.ReadKey();
}
public static void ProcessMessage(string classText, IProcessable testClass)
{
Console.WriteLine("ClassText:{0}", classText);
}
}

Inheritance Generic Invariance C#4

I've been searching why this generic contruction doesn't compile
I get:
Cannot implicitly convert type 'WpfApplication1.CowDao' to 'WpfApplication1.Dao'
public abstract class Animal { }
public class Dog : Animal { }
public class Cow : Animal { }
public abstract class Dao<T> where T : Animal
{
public void Insert(T t);
}
public class DogDao : Dao<Dog> { }
public class CowDao : Dao<Cow> { }
public class Main
{
public Main()
{
Dao<Animal> dao = null;
if (true) dao = new DogDao();
else dao = new CowDao();
}
}
I just want to get to my goal --> making a 'neutral' instance
I think that my construction has to change, but i don't know how
I'm using .NET Framework 4
Thanks
Generics from a derived does not inherit from Generic from a base class so you may not cast one to another. Instead, write an extension method ToGenericParent that converts like that:
public static Generic<Parent> ToGenericParent(this Generic<Derived> derived)
{
return new Generic<Parent>() { Value = derived.Value };
}
Change your Inheritance for your Dao layers as
public class DogDao : Dao<Animal> { }
public class CowDao : Dao<Animal> { }
Edit:
public abstract class Dao<T> where T : Animal
{
public virtual void Insert(T t)
{
}
protected void ExecuteQuery(string quer)
{
}
}
public class DogDao : Dao<Dog>
{
public override void Insert(Dog t)
{
string insert = "INSERT INTO DOG ...";
base.ExecuteQuery(insert);
}
}
public class CowDao : Dao<Cow>
{
public override void Insert(Cow t)
{
string insert = "INSERT INTO COW ...";
base.ExecuteQuery(insert);
}
}

Ninject summon graphs with argument

Here is my problem. I have a presenter class, lets call it 'Presenter' that takes an IDataSource as a constructor argument. There are different implementations of the IDataSource interface. I would like to be able to pass some argument to Ninject and based on that argument one of several IDataSource implementations should by used. I've provided some sample code below. I think that my solution is really ugly and that there must be a smarter, cleaner way to do this. How are you guys solving this type of problem?
Here is my sample code
public class Presenter
{
public Presenter(IDataSource dataSource)
{
DataSource = dataSource;
}
private IDataSource DataSource { get; set; }
public List<string> GetData()
{
return DataSource.GetAll();
}
}
public class InMemoryDataSource : IDataSource
{
public List<string> GetAll()
{
return new List<string> {"a", "b"};
}
}
public class DbDataSource : IDataSource
{
public List<string> GetAll()
{
return new List<string> { "1", "2" };
}
}
public interface IDataSource
{
List<string> GetAll();
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<Presenter>().To<Presenter>().Named("Db");
Bind<Presenter>().To<Presenter>().Named("InMemory");
Bind<IDataSource>().To<InMemoryDataSource> ().WhenParentNamed("InMemory");
Bind<IDataSource>().To<DbDataSource>().WhenParentNamed("Db");
}
}
[Test]
public void Run()
{
using (var kernel = new StandardKernel(new Module()))
{
var p = kernel.Get<Presenter>(x => x.Name == "InMemory");
foreach(var s in p.GetData())
{
Console.Out.WriteLine(s);
}
}
}
This depends on what you want to do. I assume that you want to use a different db for testing than for production. In this case would create the module with the production configuration in mind and simply Rebind everything for testing:
public class Presenter
{
public Presenter(IDataSource dataSource)
{
DataSource = dataSource;
}
private IDataSource DataSource { get; set; }
public List<string> GetData()
{
return DataSource.GetAll();
}
}
public class InMemoryDataSource : IDataSource
{
public List<string> GetAll()
{
return new List<string> {"a", "b"};
}
}
public class DbDataSource : IDataSource
{
public List<string> GetAll()
{
return new List<string> { "1", "2" };
}
}
public interface IDataSource
{
List<string> GetAll();
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<Presenter>().To<Presenter>();
Bind<IDataSource>().To<DbDataSource>();
}
}
[Test]
public void Run()
{
using (var kernel = new StandardKernel(new Module()))
{
kernel.Rebind<IDataSource>().To<InMemoryDataSource>();
var p = kernel.Get<Presenter>();
foreach(var s in p.GetData())
{
Console.Out.WriteLine(s);
}
}
}

Resources