implements with different data type - java

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.

Related

Unkown Class error trying to implement dependency injection

I'm using generics to get my code reusable and to utilize dependency injection.
I have two Interfaces: DataParserImplementation and ObjectImplementation. I have classes that implement each: SalesRepbyId implements DataParserImpl (it parses the data into objects and puts those objects into collections). SalesRep implements Objectimpl (It is the object for a specific dataset).
I'm trying to get it so that I can select which kind of Objectimpl I use in my SalesRepbyId class so I can remove the coupling.
I know there is something called reflection that I've been told is the method I need to use. I also have heard about a "Factory Pattern" and a "Properties file" that allows me to do what I want to do. A lot of this is very confusing so please explain it like I'm five.
Here is the code with where it stops working:
EDIT: Revisions based on comments: I want to specify the type of DataObject (D) my class uses by passing it through the constructor via a common interface and using generic types. When I try and use it instead of a concrete implementing class, I get the error. I can't find anything about this error.
public class SalesRepbyId<D extends ObjectImplementation> implements DataParserImplementation<Map<String,D>> {
private FileParserImplementation<ArrayList<String[]>> FileParser;
private D dataObject;
public SalesRepbyId(FileParserImplementation<ArrayList<String[]>> FileParser,D d){
this.FileParser = FileParser;
this.dataObject = d;
}
#Override
public Map<String, D> Parse() {
try{
//reads the file and returns an array of string arrays
ArrayList<String[]> Salesrep_contactlist = FileParser.ReadFile;
//here it still says "Unknown Class." that's the problem
Map<String, dataObject> SalesrepByIdMap = new HashMap<>();
//I want to be able to put in any class that implements
//dataObject into this class and have it run the same way.
Summary of what I did
I Implemented the Factory Design pattern and created a properties file which allowed me to reflect in the class I wanted instead of trying to use a generic DataObject (or D) type.
Details of Solution
Reflecting the class using the properties file "config.properties" and then casting it to type Objectimplementation allowed me to use any class that implemented that interface (and was implemented in the Factory and set in the properties file). I then refactored all instances of D to type ObjectImplementation since the parent interface is the layer of abstraction needed here rather than a generic concrete class.
Why it didn't work the way I tried it in the question
the reason the generic D type doesn't work with reflection is because reflection uses a concrete classtype determined at runtime and the generic D type is specified before runtime. Thus I was trying to reflect in the classtype and its methods/instances without properly using reflection and the code was telling me that the classtype was unknown at the time I needed it.
Code example to compare to the Question code
Example of the working code:
public class SalesRepbyId implements
DataParserImplementation<Map<String,ObjectImplementation>> {
private FileParserImplementation<ArrayList<String[]>> FileParser;
//the Factory class that creates instances of the reflected class I wanted
private ObjectFactory Factory = new ObjectFactory();
public Map<String, ObjectImplementation> Parse() {
//the proeprties object which then loads properties from a file and reflects the classtype I want
Properties prop = new Properties();
//loading in the classtype and casting it to the subclass of ObjectImplementation that it actually is
prop.load(SalesRepbyId.class.getResourceAsStream("config.properties"));
Class<? extends ObjectImplementation> Classtouse = Class.forName(prop.getProperty("ObjectImplementation")).asSubclass(ObjectImplementation.class);
//construct instances of 'Classtouse' and parse the data into these dynamically typed objects
//return the map that holds these objects
}

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 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();
}
}

jsf Converter: How to find out the class type of the actual passed value String?

I'm trying to bind custom class objects together with MyFaces UI-components like checkboxes/combos, etc. but without giving the explicit type like int/float/boolean/String/List<String> by creating the getters/setters in the backing bean.
So in my case it will usually look like this:
<h:selectOneListbox id="mylist" value="#{bean.myListValueHolder.data}"
converter="myValueConverter">
...
</h:selectOneListbox>
Where:
bean is backing bean
myListValueHolder is of type MyValueHolder<T>
data is of type <T>
I'm trying to use a custom Converter for it and this class signature:
public class MyValueHolder<T extends Comparable<T>> extends Node<T> {
....
MyValueHolder has this methods:
public T getData() {
...
public void setData(Object data) {
...
public void setData(T data) {
...
My Converter:
public Object getAsObject(FacesContext fc, UIComponent c, String value) {
...
The problem: how can I find out the type <T> passed as value at the runtime? It can be a boolean, int, float, double, String, or List<String> in my case.
But I kinda dislike to write
A lot of "try to cast to a type and if it succeeds, its your type" but without knowing for sure, whether its a int or a float/double.
Giving the type as a parameter or as second parameter as I define my h:selectOneListbox
???
How can I achieve this?
EDIT: OK, List would not work. But the question is, is it any good to bind values from JSF UIComponents in my view to some kind of a value wrapper to avoid write to many simple "dummy" getters/setters in my backing beans?
So I could use "one" bean which will have the MyValueHolder accessible by Key (property name which is a String) like "bean.get('property_name')" or over "#{bean.myListValueHolder.data}" or similar syntax?
EDIT2: To answer BalusC question and to explain the Why.
As for now, I'm not sure whether this approach is a good one.
My data comes as XML, I parse it to save it as key, value pairs. My UI-elements have also a particular state(s) (EnumSet from a State-Enum {hidden, visible, disabled, enabled, hover, focus, active, ...} which is dependent from specific values stored in ValueHolders. The dependency of required State(s) is described in a Rule class, which has an EnumSet of State and a matches method, which returns true if the defined State shall be applied because the Rule matches. Then I have a ValueChangedListeners which shall apply new State(s) to the UI-Components if the Value has been changed and the Rules associated with that Value match.
At least this is how I thought, I can do this. So I can query for value and ui-state from my view and if some concrete value changes, which in turn might change the State of the UIComponent I can invoke a callback and depending on the new State add/remove a new css class to that particular component via JQuery.
Well, sounds kinda complex or pretty overkill, but I want to define my UI-Component States in Java, so I can change the State from Java too and not having the State-Rules defined in the view.
A JSF Converter is not suitable for this. You need a custom ELResolver for this. Extending BeanELResolver and overriding getType(), getValue() and setValue() wherein you grab the concrete ValueHolder implementation should do it. This way you can ultimately end up with expressions like value="#{bean.myStringValueHolder}" without the .data. This way the data coercion/conversion will then automatically be done by JSF/EL.
You can register the custom EL resolver on application's startup by Application#addELResolver():
FacesContext.getCurrentInstance().getApplication().addELResolver(new ValueHolderELResolver());
As to figuring the generic type, assuming that ValueHolder is an abstract class and you've concrete implementations like StringValueHolder extends ValueHolder<String> and so forth, then you'll be able to extract the generic type in the constructor of ValueHolder.
public abstract class ValueHolder<T extends Comparable<T>> extends Node<T> {
private Class<T> type;
private T data;
#SuppressWarnings("unchecked")
public ValueHolder() {
this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getType() {
return type;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setData(Object data) {
this.data = type.cast(data);
}
}
I only wonder how this entire approach is useful. There's some seemingly unnecessary overhead. What exactly is the functional requirement? It is just eliminating getter/setter boilerplate? Why not just using model objects (javabeans/entities/etc) so that you end up with only one model property in the backing bean? Is it being tired of typing them everytime? A bit decent IDE can autogenerate them. Even more, complete javabean classes can be autogenerated based on a list of property names and a few clicks.
You could add a instance of your converter to your bean and bind it to your input element, then you know the type. This way you could also pass the objects to convert to the converter via a constructor and perform simple lookup. Not that handsome but it would work.

Cast an object dynamically from a string

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();

Categories