Getting name of the variable for class in groovy - groovy

I am using Groovy Expando class to hold some properties and methods. I want to prevent accidental setting of the same property multiple times such as below
e = new Expando()
e.var1 = 'abc'
e.var1 = 'cde'
In order to do that I created a new class that extends Expando like below
class MyExpando extends Expando {
void setProperty(String property, Object newValue) {
if(this.getProperty(property)){
throw new RuntimeException("duplicate declaration of $property in ${this.class.name}")
} else {
super.setProperty(property, newValue)
}
}
}
This works so it throws RuntimeException but I want the error message to be like Duplicate property var1 in e. Now the question is how to get e

Related

Apache Calcite - ReflectiveSchema StackoverflowError

I'm trying to create a simple schema using ReflectiveSchema and then trying to project an Employee "table" using Groovy as my programming language. Code below.
class CalciteDemo {
String doDemo() {
RelNode node = new CalciteAlgebraBuilder().build()
return RelOptUtil.toString(node)
}
class DummySchema {
public final Employee[] emp = [new Employee(1, "Ting"), new Employee(2, "Tong")]
#Override
String toString() {
return "DummySchema"
}
class Employee {
Employee(int id, String name) {
this.id = id
this.name = name
}
public final int id
public final String name
}
}
class CalciteAlgebraBuilder {
FrameworkConfig config
CalciteAlgebraBuilder() {
SchemaPlus rootSchema = Frameworks.createRootSchema(true)
Schema schema = new ReflectiveSchema(new DummySchema())
SchemaPlus rootPlusDummy = rootSchema.add("dummySchema", schema)
this.config = Frameworks.newConfigBuilder().parserConfig(SqlParser.Config.DEFAULT).defaultSchema(rootPlusDummy).traitDefs((List<RelTraitDef>)null).build()
}
RelNode build() {
RelBuilder.create(config).scan("emp").build()
}
}
}
I seem to be correctly passing in the "schema" object to the constructor of the ReflectiveSchema class, but I think its failing while trying to get the fields of the Employee class.
Here's the error
java.lang.StackOverflowError
at java.lang.Class.copyFields(Class.java:3115)
at java.lang.Class.getFields(Class.java:1557)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:76)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:160)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:151)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:84)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createType(JavaTypeFactoryImpl.java:160)
at org.apache.calcite.jdbc.JavaTypeFactoryImpl.createStructType(JavaTypeFactoryImpl.java:84)
What is wrong with this example?
Seems that by just moving the Employee class a level above, ie. making it a sibling of the DummySchema class, makes the problem go away.
I think the way the org.apache.calcite.jdbc.JavaTypeFactoryImpl of Calcite is written doesn't handle Groovy's internal fields well.

How to cast an object in class loaded in classloader

I am new to Stack Overflow. I have created a Groovy class loader's object in which I have loaded all the classes required by my script. I have task of serializing and deserializing an object created of one of the class that is loaded in class loader. Problem is while deserializing I am not able to cast the object in the class as class in loaded in class loader. I don't know how to cast an object in a class that is loaded in a class loader. Can some one help me in this. The ????? in below snippet is a class that is loaded in class loader but how shall I achieve this.
Object o = null
new ByteArrayInputStream(bytes).withObjectInputStream(getClass().classLoader){ gin ->
o = (?????)gin.readObject() }
Thanks in advance!!!
I managed to solve your problem. Let me show you a working example
Some Employee class, that I use
public class Employee implements java.io.Serializable
{
public String name;
public String address;
}
Then the Main class
class Main {
public static void main(String[] args) {
Employee e1 = new Employee()
e1.name = 'John'
e1.address = 'Main Street'
byte[] bytes = []
ByteArrayOutputStream stream = new ByteArrayOutputStream()
ObjectOutputStream out = new ObjectOutputStream(stream)
out.writeObject(e1)
bytes = stream.toByteArray()
out.close()
stream.close()
Object o = null
new ByteArrayInputStream(bytes).withObjectInputStream(Main.getClassLoader()){ gin ->
o = gin.readObject()
}
print o instanceof Employee
println 'Deserialized Employee...'
println 'Name: ' + o.name
println 'Address: ' + o.address
}
}
Instead of doing getClass().classLoader, which was throwing a java.lang.ClassNotFoundException, I am doing Main.getClassLoader(). This classloader is able to find my Employee class.
Moreover, you don't really need to cast the object, it is groovy, its dynamic, so you get the name and address fields at runtime.
But, you can always check the type of the object and then cast it:
print o instanceof Employee
this will return true

How can I specify which instances of a class are unmarshalled using an XMLAdapter?

I have the following java class and have placed an XmlJavaAdapter annotation on the payerPartyReference variable. I want the adapter PartyReferenceAdapter to be used for unmarshalling ONLY this variable, not any other variables which have the same type of PartyReference, whether in this class or some other class. How can I do this? Thanks for your help!
public class InitialPayment extends PaymentBase
{
// Want PartyReferenceAdapter to be used here
#XmlJavaTypeAdapter(PartyReferenceAdapter.class)
protected PartyReference payerPartyReference;
//
// Dont want PartyReferenceAdapter to be used here
protected PartyReference receiverPartyReference;
//
protected AccountReference receiverAccountReference;
#XmlSchemaType(name = "date")
protected XMLGregorianCalendar adjustablePaymentDate;
#XmlSchemaType(name = "date")
protected XMLGregorianCalendar adjustedPaymentDate;
protected Money paymentAmount;
}
My Adapter is defined as follows:
public class PartyReferenceAdapter
extends XmlAdapter < Object, PartyReference > {
public PartyReference unmarshal(Object obj) throws Exception {
Element element = null;
if (obj instanceof Element) {
element = (Element)obj;
String reference_id = element.getAttribute("href");
PartyReference pr = new PartyReference();
pr.setHref(reference_id);
return pr;
}
public Object marshal(PartyReference arg0) throws Exception {
return null;
}
}
Field/Property Level
If you set #XmlJavaTypeAdapter on a field/property it will only be used for that property.
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
Type Level
If you set #XmlJavaTypeAdapter on a type, then it will used for all references to that type.
http://bdoughan.blogspot.com/2010/12/jaxb-and-immutable-objects.html
Package Level
If you set #XmlJavaTypeAdapter on a package, then it will be used for all references to that type within that package:
http://bdoughan.blogspot.com/2011/05/jaxb-and-joda-time-dates-and-times.html

how to avoid change of class on assigning derived class object to base class object in c# 4?

Hello from C# and OOP newbie.
How can I avoid change of class on assigning derived class object to base class object in c#?
After i run code bellow i get this response
obj1 is TestingField.Two
obj2 is TestingField.Two
I expected that i will lose access to derived methods and properties (which I did) after assigning reference but I did not expect change of class in midcode :S
using System;
namespace TestingField
{
class Program
{
static void Main(string[] args)
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1 is {0}", obj1.GetType());
Console.WriteLine("obj2 is {0}", obj2.GetType());
Console.ReadLine();
}
}
class One
{
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
}
}
While you are right, you will lose access to members declared in the derived type, the object won't suddenly change it's type or implementation. You can access only members declared on the base type, but the implementation of the derived type is used in the case of overriden members, which is the case with GetType, which is a compiler generated method which automatically overrides the base class's implementation.
Extending your example:
class One
{
public virtual void SayHello()
{
Console.WriteLine("Hello from Base");
}
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
public override void SayHello()
{
Console.WriteLine("Hello from Derived");
}
}
Given:
One obj = new Two();
obj.SayHello(); // will return "Hello from Derived"
GetType is a virtual method gives you the dynamic type of the object.
I think you want the static type of the variable. You can't get this by calling a method on the object referenced by the variable. Instead just write typeof(TypeName), which is typeof(One) or typeof(Two) in your case.
Alternatively in your subclass you can use a new method which hides the original one instead of overriding it:
class One
{
public string MyGetType() { return "One"; }
}
class Two : One
{
public new string MyGetType() { return "Two"; }
}
class Program
{
private void Run()
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1.GetType(): " + obj1.GetType());
Console.WriteLine("obj2.GetType(): " + obj2.GetType());
Console.WriteLine("obj1.MyGetType(): " + obj1.MyGetType());
Console.WriteLine("obj2.MyGetType(): " + obj2.MyGetType());
}
}
Result:
obj1.GetType(): Two
obj2.GetType(): Two
obj1.MyGetType(): One
obj2.MyGetType(): Two
You haven't "changed class". The type of the variable obj1 is still One. You have assigned an instance of Two to this variable, which is allowed since Two inherits from One. The GetType method gives you the actual type of the object currently referenced by this variable, not the type of the declared variable itself.

Adding new dynamic properties

we read in msdn we "Adding new dynamic properties" by using DynamicObject Class
i write a following program
public class DemoDynamicObject : DynamicObject
{
}
class Program
{
public static void Main()
{
dynamic dd = new DemoDynamicObject();
dd.FirstName = "abc";
}
}
But when i run this program it gives runtime error :'DemoDynamicObject' does not contain a definition for 'FirstName'
if we adding dynamic property by using DynamicObject Class then why it can give this error
can anyone tell me reason and solution?
When using DynamicObject as your base class, you should provide specific overrides to TryGetMember and TrySetMember to keep track of the dynamic properties you are creating (based on the DynamicObject MSDN documentation):
class DemoDynamicObject: DynamicObject
{
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
string name = binder.Name;
return dictionary.TryGetValue(name, out result);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
If you just want to have a dynamic object that you can add properties to, you can simply use an ExpandoObject instance, and skip the custom class inheriting from DynamicObject.

Resources