Cast an object dynamically from a string - java

I'm writing a servlet-filter as the solution of this question:
Is it a good idea to filter inside a JSF template?
now, the idea is to create a big filter to check all privilegies and give the access or not to a certain user.
I create a Map to contains all privilegies for all sub applications and it has the sub application's id (a Long value) as Key and for the value another Map that contains other important informations.
The controller classes are named class1Controller, class2Controller ecc and the subapplications are stored in many folder named class1, class2 ecc...
The last thing that I must say is that all classes have a parameter called applicationID that is the same key of the Map that I mentioned previously.
So, what I would do?
I can retrieve the subapplication visited by the user using getRequestURI() method from HttpServletRequest, the problem is that I should take the application id from the class linked to that application, so I wrote this code:
Long id= ((Class.forName(packageName+applicationName+"Controller"))session.getAttribute(applicationName+"Controller")).getApplicationId();
The problem is that the compiler returns that it can't find method getApplicationId()!
Can I do something to resolve this problem? Or I must find another way to do that?

The last thing that I must say is that all classes have a parameter called applicationID
It sounds like you want an interface with the getApplicationId method in; make all the controllers implement that interface, and then all you need to do is cast to that interface.
// TODO: Work out a better interface name than "Application" :)
Object attribute = session.getAttribute(applicationName+"Controller");
Long id = ((Application) attribute).getApplicationId();
(You might want to use an abstract base class as described by BalusC - they're variations on the same theme, really.)

You're calling getApplicationId() on a Class instance, but it does not have that method at all.
The normal approach is to let all those classes extend some common base abstract class or an interface which has the method definied and then cast to that base abstract class or interface instead.
E.g. with a base abstract class:
public class FooController extends BaseController {}
public class BarController extends BaseController {}
etc..
Where the base abstract class look like this:
public abstract class BaseController {
public Long getApplicationId() {
return applicationId;
}
}
Then you can get it as follows:
Long id = ((BaseController) session.getAttribute(applicationName + "Controller")).getApplicationId();

Related

How to retrieve implementing class/interface of parent interface?

I am clear with polymorphism and inheritance concept of oop, but I am in a situation where I need to know the implementing class. For example:
public CommonReadRepository<?> getReadRepository(String tableName) {
if (tableName == null)
return null;
switch (tableName) {
case "order":
return orderRepository;
...
}
return null;
}
The interface orderRepository extends CommonReadRepository, and because of my requirement, I need to access a function defined in orderRepository.
CommonReadRepository<?> repository=getReadRepository("order");
Is there any way to check back the implementing (child) class or interface of CommonReadRepository?
Of course, I can always do something like this:
if(tableName=="order")
return (OrderRepository)CommonReadRepository<?>;
I tried to debug getReadRepository("order"), but it gives me an instance of JdkDynamicAopProxy, and I am not sure how it works.
if(interface is instanceof xyz class)
i do not want to use it because i have 100 of classes and i want to keep it as a last resort... or in other words
i don't know about xyz class
Thanks
Following is one way to check if the returned Object is an instance of the specified class:
CommonReadRepository<?> repository=getReadRepository("order");
if(repository instanceof WhatEverSubclass) {
// do something
}
But using this approach is not how OOP is supposed to be done. If your classes all implement the same Interface, why don't you define a common method, that's then used in all the subclasses, but implement it differently every time.
I think, what you try to do is not getting you anywhere.
You can find all available classes inheriting an interface using the reflections tool (https://github.com/ronmamo/reflections). I used it for a dependency injector and it works very reliable.
Yet, why don't you just use the instanceof operator to make sure the object is of the right type:
if( repository instanceof OrderRepository) return (OrderRepository)repository;
But still, this won't change the return type of your function and you need to inspect the type of the returned value again outside of your function.
Update: If this happens for hundreds of objects, you could change the getRepository method to return a type you give as parameter: <T> getRepository(String name, Class<T> expectedType)
This will allow you OrderRepository o = getRepository("order", OrderRepository.class);

How to create class from class canonical name in java?

I have class canonical name like this dev.ashish.mvc.beans.Employee.
Using this how can i create Class Employee at runtime in order access data members and member functions of Employee.
At runtime i want create class using its canonical name. At times it can be any entity Employee,Customer,User etc.
I tried this :
Class entityClass = Class.forName("dev.ashish.mvc.beans.Employee");
the above code does return class if i do entityClass.getName() it does return me dev.ashish.mvc.beans.Employee but how can i access methods of class Employee .
If i use java reflection like below :
Field field [] = entityClass.getClass().getDeclaredFields();
it returns me declared fields of class java.lang.Class instead of dev.ashish.mvc.beans.Employee
How can i achieve this ???
You already have your class in entityClass, so calling entityClass.getClass() will give you java.lang.Class and entityClass.getClass().getDeclaredFields() will indeed give you methods of Class not of your particular class.
You need:
Field field [] = entityClass.getDeclaredFields();
When you did:
Class entityClass = Class.forName("dev.ashish.mvc.beans.Employee");
you just got class of Employee. Now you have to create instance of it:
Employee employee = (Employee) entityClass.newInstance();
Update:
My answer is wrong. I though you need to work with methods of instance. But you need to access class methods.
You can call a method by name thus (adding to what has already said by others)
Method methodToCall = cls.getMethod("method_name");//cls is of type Class (e.g Employee.class)
methodToCall.invoke(obj, args);//obj is of type Employee in your case
Note that cls is of type Class and you already have to have an instance of the class that you want to call a method on. Note that even if you're calling a method without arguments you still have to pass a class instance (obj in this example), which means that the first argument is always a class instance.

How can I add my own EnumValueMapperSupport

I'm trying to persist some enums in Hibernate and it looks like my two options for built in support are to use the name of the enum, which I would rather not do because it's string based instead of int based, or the ordinal of the enum, which I would rather not do because if I add one of the enum values at the top of the class later on, I break everything down the line.
Instead, I have an interface called Identifiable that has public int getId() as part of its contract. This way, the enums I want to persist can implement Identifable and I can know that they'll define their own id.
But when I try to extend EnumValueMapperSupport so I can utilize this functionality, I'm greeted with errors from the compiler because the EnumValueMapper interface and the EnumValueMapperSupport class are not static, and thus are expected to be locked into a given EnumType object.
How can I extend this functionality in Hibernate, short of rewriting a bunch of Hibernate code and submitting a patch. If I can't, is there another way to somehow store an enum based on something other than the ordinal or name, but instead on your own code?
In a related thought, has anyone personally been down this road and decided "let's see how bad the name mapping is" and just went with name mapping because it wasn't that much worse performance? Like, is it possible I'm prematurely optimizing here?
I'm working against Hibernate version 5.0.2-final.
At least for Hibernate 4.3.5 the EnumValueMapper is static - although private.
But you can extend EnumValueMapperSupport in an extension of EnumType:
public class ExampleEnumType extends EnumType {
public class ExampleMapper extends EnumValueMapperSupport {
...
}
}
To create an instance of this mapper you need an instance of your EnumType:
ExampleEnumType type = new ExampleEnumType();
ExampleMapper mapper = type.new ExampleMapper();
Or you create it inside your type:
public class ExampleEnumType extends EnumType {
public class ExampleMapper extends EnumValueMapperSupport {
...
}
public ExampleMapper createMapper() {
return new ExampleMapper();
}
}

implements with different data type

I have 2 class just call it "Stuff" and "Customer", the classes based on my database table (JDBC) and have abstract class because this 2 classes has same few property(Id,Name), my abstract class containing(Id,Name, along with setter and getter from Id and Name variable).
I was creating 2 more class ("ExecuteStuff" and "ExecuteCustomer") which has a goal to execute a query for manipulate a data in my database,because this situation "ExecuteStuff and ExecuteCustomer" class should have method insert, update,delete and show for manipulate and showing a data from my database, because "ExecuteStuff" and "ExecuteCustomer" need a same method for process a data from my database , I decided to creating my own interface called "myData" which is contain 4 mehod (insertData(), updateData(),deleteData() and showData()) for class "ExecuteStuff" and class "ExecuteCustomer".
My problem is, what type data should I use for parameter inside a method in my interface "myData", for example = public int insertData(Stuff stuff); this method will work for "ExecuteStuff" but not for "ExecuteCustomer" because "ExecuteStuff" and "ExecuteCustomer" has a different object type.
Or a graceful way to solve this problem.
If I understand you correctly, you can use a generic type in your interface. That way it won't matter what the data type of the parameter you pass in is.
Here is a link that explains generics:
https://docs.oracle.com/javase/tutorial/java/generics/types.html
Another solution is to use:
public int insertData(Object obj);
Since both Stuff and Customer are objects.
Hope I was able to help!
You could use a generic parameter:
interface MyData {
public <T> T insertData(T data);
}
Class example:
class MyCustomClassThat implements MyData{
#Override
public <T> T insertData(T data) {
return data;
}
}
This makes the insertData method accept any class. Then you can operate on it however you like. Finally, we return the object originally presented; just in case you operated on the data object itself.

Prototyping in Java instead of extending

Is Javascript-like prototyping anyhow achievable, even using Reflection? Can I wrap my object inside another one, just to extend its functionality with one or two more methods, without wiring all its original nonprivate methods to the wrapper class, or extends is all I get?
If you are looking for extension methods, you could try Xtend. Xtend is language that compiles to java code and eliminates boilerplate code.
The following text is stolen from the Xtend Docs for extensions:
By adding the extension keyword to a field, a local variable or a parameter declaration, its instance methods become extension methods.
Imagine you want to have some layer specific functionality on a class Person. Let us say you are in a servlet-like class and want to persist a Person using some persistence mechanism. Let us assume Person implements a common interface Entity. You could have the following interface
interface EntityPersistence {
public save(Entity e);
public update(Entity e);
public delete(Entity e);
}
And if you have obtained an instance of that type (through a factory or dependency injection or what ever) like this:
class MyServlet {
extension EntityPersistence ep = Factory.get(typeof(EntityPersistence))
...
}
You are able to save, update and delete any entity like this:
val Person person = ...
person.save // calls ep.save(person)
person.name = 'Horst'
person.update // calls ep.update(person)
person.delete // calls ep.delete(person)
I don't think you can do this in Java. You can though in Groovy, using metaclasses
String.metaClass.world = {
return delegate + " world!"
}
println "Hello".world()

Categories