Check getter value by list of property name - java

First of all, sorry if my question seems basic. I suppose I have one class with 100 properties and 100 getters and setters.
I'm aiming check not null value of some of these properties.
Exemple :
If (object.getPropertyName()==null) System.out.println(" null value of Property Name")
I wana do this for 50 properties. I could provide a list of properties to be checked in input. Is there anyway to capture getter name by property name and check them one by one without writing this 50 times ?
Thanks

Yes sure, you can use this library here: de.cronn.reflection-util.
It allows you to obtain descriptors from specific field names and then call their respective get/set methods. Like in the following source code:
public class Test {
public static void main(String[] args) {
Example example = new Example();
example.setName("Test");
PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptorByName(example, "name");
System.out.println((String) PropertyUtils.read(example, descriptor)); // Will call getName
}
}
public class Example {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Related

Is it possible to build an object like this at runtime in java?

As the title says....
I want to build a POJO with four field variables and at certain runtime events create an instance of this POJO with access to possibly maybe two or three of the fields.
public class Category implements Serializable {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Lets say I create a new Category object but I only want to be able to have access to the name field during runtime. Is there a design pattern I can use to achieve this? I thought about the strategy pattern and looked at the builder but I am still confused if I can do this in java.
Basically the overall goal is to grab an object from a database and return it as a JSON response in jax rs. But sometimes I dont want a complete object returned but only lets say halve of the object to be accessible at during certain runtime events. My apologies if this seems like a dumb question but I know what I want to do but just don't know the best way.
I have the same problem with you, and my project was used springmvc,and the json tool is jackson.With the problem solved, I just use #JsonIgnore.For more details,just read jackson-how-to-prevent-field-serialization
So someone correct me if I am wrong or see a better option than this...with alot of objects this can be alot of extra code for serialization and deserialization...Jackson Provisions is what I need. I can use the annotation #JsonView(DummyClass.class) on the field variable. I will accept this a the best answer in a day or two unless someone else posts a better response.
// View definitions:
class Views {
static class Public { }
static class ExtendedPublic extends PublicView { }
static class Internal extends ExtendedPublicView { }
}
public class Bean {
// Name is public
#JsonView(Views.Public.class) String name;
// Address semi-public
#JsonView(Views.ExtendPublic.class) Address address;
// SSN only for internal usage
#JsonView(Views.Internal.class) SocialSecNumber ssn;
}
With such view definitions, serialization would be done like so:
// short-cut:
objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);
// or fully exploded:
objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
// (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
objectMapper.writeValue(out, beanInstance); // will use active view set via Config
// or, starting with 1.5, more convenient (ObjectWriter is reusable too)
objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
This information was pulled from http://wiki.fasterxml.com/JacksonJsonViews
with jackson 2.3, I can do this with JAX-RS
public class Resource {
#JsonView(Views.Public.class)
#GET
#Produces(MediaType.APPLICATION_JSON )
public List<Object> getElements() {
...
return someResultList;
}
}

How to handle null check in generic way in Java?

I have to check null condition for too many methods. how can i do it in generic way rather than repeating the same steps or Is it possible to write?
Here's my code:
<Student>
<Name></Name>
<RollNumber></RollNumber>
</Student>
I should throw an exception If user gives null value for Name or RollNumber field. I have already written code below. which is working correctly but i need to write generic method for both scenario and it should work the same as below,
if(student.getName() == null) {
System.out.println("Name is required to create Student Data");
}
if(student.getRollNumber() == null) {
System.out.println("RollNumber is required to create Student Data");
}
Note : Name is String and RollNumber is an Integer
Can you please give me an IDEA?
This question may already have an answer here:
Avoiding “!= null” statements in Java? 44 answers
My Question is "I don't want avoiding null statement. If user gives null value How Can we throw an exception in generic way?"
If your Student bean always requires non-null values how about constructing the student object with non-null values inside a constructor. As you are doing the validation inside the constructor only no need to the do the same whenever you are using that object
public class Student
{
private String name;
private String rollNumber;
public Student(String name, String rollNumber)
{
setName(name);
setRollNumber(rollNumber);
}
public String getName()
{
return name;
}
public String getRollNumber()
{
return rollNumber;
}
public String setName(String name)
{
if(isNull(name))
{
throw new NullPointerException("Name is required to create Student Data");
}
this.name= name;
}
public String setRollNumber(String rollNumber)
{
if(isNull(rollNumber))
{
throw new NullPointerException("Roll Number is required to create Student Data");
}
this.rollNumber = rollNumber
}
private void isNull(String str)
{
if(str == null || str.trim().isEmpty())
return true;
return false;
}
}
You should probably take a look at Hibernate Validation. Then you can simply annotate the fields of your bean with #NotNull.
As a bonus you can handle other validations as well.
You can use the Apache Commons String Utils API , which defines operations on String that are null safe.
You can do something like this:-
if (StringUtils.isEmpty(student.getName()) { //this check for both empty String and null and prevents null pointer exceptions
System.out.println("Name is required to create Student Data");
}
Besides null comparison for just Strings, Assertions are good way to handle nulls you can check here for more info. Make sure to pass -ea argument to JVM as by default it ignores Assertions

How to bind a JavaFX Label to the selected item from a ListView

I have a ListView full of POJOs and want a label in the GUI to display informations from the selected item.
My POJO looks something like that:
class Customer {
private String name;
...
public String getName() {
return name;
}
Now when the user selects a customer from the list I want the name of the selected customer displayed in a label.
Obviously I can't bind to the name directly because it is not a Property. (And I don't want to replace my Customers Strings with StringProperty-objects because the SimpleStringProperty is not serializable and I need the Customer to be transfered via RMI.)
I've tried the BeanPathAdapter from JFXtras (which looks really nice by the way) like this:
BeanPathAdapter<MultipleSelectionModel> customerBeanPathAdapter;
customerBeanPathAdapter = new BeanPathAdapter<>(lstCustomers.getSelectionModel());
customerBeanPathAdapter.bindBidirectional("selectedItem.name", lblCustomerName.textProperty());
But this solution only throws me an Exception:
...
Caused by: java.lang.IllegalArgumentException: Unable to resolve accessor getSelectedItem
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3062)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessorWithLikelyPrefixes(BeanPathAdapter.java:3022)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.updateMethodHandles(BeanPathAdapter.java:2986)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.<init>(BeanPathAdapter.java:2977)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1348)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1186)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:567)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:369)
at at.gs1.sync.qm.client.gui.MainWindowController.initialize(MainWindowController.java:61)
... 22 more
Caused by: java.lang.IllegalAccessException: symbolic reference class is not public: class javafx.scene.control.ListView$ListViewBitSetSelectionModel, from jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:512)
at java.lang.invoke.MethodHandles$Lookup.checkSymbolicClass(MethodHandles.java:1113)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1094)
at java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:626)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3049)
... 30 more
So I hoped there would be a better solution than to use lstCustomers.getSelectionModel().selectedItemProperty().addListener(...) and handle the population of the labels there manually.
A better solution I think, to the one I gave before, is to use the BeanPathAdapter as you tried.
However the BeanPathAdapter needs to have the following property added to it:
private final ObjectProperty<B> beanProp = new SimpleObjectProperty<>();
{
beanProp.addListener( new ChangeListener<B>()
{
#Override
public void changed( ObservableValue<? extends B> ob, B oldVal, B newVal )
{
setBean( newVal );
}
} );
}
public ObjectProperty<B> beanProperty()
{
return beanProp;
}
Then in your code you need the following:
BeanPathAdapter<Customer> custBean;
custBean = new BeanPathAdapter<>( new Customer() ); // empty or any customer
custBean.bindBidirectional( "name", label.textProperty() );
custBean.beanProperty().bind( listview.getSelectionModel().selectedItemProperty() );
I don't think that there's a simple one liner that you are looking for.
You could do the following:
label.textProperty().bind( Bindings.selectString( listview.getSelectionModel().selectedItemProperty(), "name" ) );
But you will need to modify your Customer POJO like so:
class Customer
{
private String name;
...
public String getName() { return name; }
public ReadOnlyStringProperty nameProperty()
{
return new SimpleStringProperty( name );
}
}
I don't think this is recommended though because properties are expected to reflect changes in the underlying data and the above will only reflect the name as it was when nameProperty is called. So if setName is called the property won't reflect the change. If the Customer name never changes then you could get away with this.

keep track of an instance attributes changes

We are working on a multi process projects which use RMI for RPCs.
The problem that we are facing is that the main object which must be passed between processes is very big (when serialized), and this dropped the performance of the code dramatically.
Since, none of the processes change the whole object and only alter small parts of it, we decided to just pass "the modifications" through RMI.
but I found no proper way to implement such concept. The first idea was to keep track of all changes of the main instance. But this seems not easy according to this.
I need a way which we can:
develop fast
performs fast
any suggestion?
Just make this 'main object' a remote object that implements a remote interface, and export it, instead of serializing it backwards and forwards.
I think the best way is to customize your serialization so you will be able to send only the changes. you can do it by implementing private method of
private void writeObject(java.io.ObjectOutputStream stream) and of course also readObject from the other side. well, what you should do in this functions?
I suggest you will manage a bitmap of all the members that were changed and only send them in the serialization, just change the unchanged members to null send the object in serialization and than return there values. in the other side read the bitmap and than you will know how to
First time you need to pass the whole object.
Use PropertyChangeListener on the object, this would generate an PropertyChangeEvent.
You can pass the PropertyChangeEvent around. It has the getSource(), by which you can identify the object. If this is not enough, if you need IOR or any other sort of reference, create a wrapper and sent it across..
-Maddy
Have a look to http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
public class Test {
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
pcs.firePropertyChange("name", oldName, name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
int oldAge = this.age;
this.age = age;
pcs.firePropertyChange("age", oldAge, age);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public Test(){
}
public static void main (String[] args){
Test myTestObject = new Test();
myTestObject.addPropertyChangeListener(new MyPropertyChangeListener());
myTestObject.setAge(12);
myTestObject.setName("Rick");
myTestObject.setName("Andrew");
}
private static class MyPropertyChangeListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent event) {
String clazz = event.getSource().getClass().getName();
System.out.println(clazz+"::"+event.getPropertyName()+" changed from "+event.getOldValue()+" to "+event.getNewValue());
}
}
}
This is a simple example but using this approach you can create different PropertyChangeListeners and provide different logic inside theirs method propertyChange.
Also is possible to fire only the changes over a small set of attributes and not over all of them (not storing the oldValue and not firing the firePropertyChange method of PropertyChangeSupport).
Of course that you can use AOP, but perhaps you are looking for a solution like presented above. I hope this helps.

using eclipse template to create test cases

Often do I find myself creating the same unit tests methods to getters\setters, c'tors and Object methods (hashCode, equals and toString).
What I'm trying to achieve, with the help of Eclipse IDE, is automation of this procedure.
consider this example:
public Class Person {
private String id;
private String name;
public Person(String id, String name){
this.id = id;
this.name = name;
}
public String getId() { return id; }
public void setId(String id) {
this.id = id;
}
public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
#override
public int hashCode(){ ... }
public boolean equals(Person other){ ... }
public String toString(){ ... }
/* this class may implement other logic which is irrelevant for the sake of question */
}
The unit test class will look something like this:
public class PersonTest extends TestCase
{
#override
public void setup() {
Person p1 = new Person("1","Dave");
Person p2 = new Person("2","David");
}
#override
public void tearDown() {
Person p1 = null;
Person p2 = null;
}
public void testGetId() {
p1.setId("11");
assertEquals("Incorrect ID: ", "11", p1.getId());
}
public void testGetName() { /* same as above */ }
public void testEquals_NotEquals() { /* verify that differently initialized instances are not equals */ }
public void testEquals_Equals() { /* verify that an object is equals to itself*/ }
public void testHashCode_Valid() { /* verify that an object has the same hashcode as a similar object*/ }
public void testHashCode_NotValid() { /* verify that different objects has different hashcodes*/ }
public void testToString() { /* verify that all properties exist in the output*/ }
}
This skeleton is similar to the vast majority of classes created.
can it be automated with Eclipse?
Have a look at Fast Code. It is an eclipse plugin that provides very nice feature of templating stuff which is what you seem to be looking for. On the documentation page look for Create Unit Test section.
A very useful feature of this plugin is to create unit tests automatically. Unit tests can be of type Junit 3, Junit 4 or TestNG. For Junit 4 or TestNG tests, appropriate annotations will be automatically added. One needs to configure it just once.
Unit tests are meant to show that an Object's behaviour is conforming to it's expected behaviour. They are not meant to make sure that the Java language is working correctly.
What you have here is a fancy data structure, with no behaviour. In that case every assignment is mediated by a method call, and every dereference is also mediated by a method call. Since Object Oriented programming is "data + behaviour" = objects, and this code lacks behaviour, it's a candidate for being called non-object-oriented code.
Sometimes Java uses non-object-oriented classes to facilitate transfer of information. The class guarantees that all information gets transferred as one unit when doing serialization. So having such a class isn't an indicator that the code is wrong; however, if you run into too many classes like this then something is very wrong.
One key element of testing is that it's not really a test if the test cannot fail. If the test cannot fail, it's just busywork. Assuming that one of these fields cannot be null then the setter might look like
public void setName(String name) {
if (name == null) throw new IllegalArgumentException("name cannot be null");
this.name = name;
}
And then you have something to test. Otherwise, your just checking to see if the assignment operator failed. As an aside, if the assignment operator failed, then I'd wager that the JVM is going to come down pretty hard sooner (rather than later) and you can't trust your tests to report correctly either.

Categories