2

Note this is not multi-threading case Old value is saved in cache, new value is getting from server and final value is updated-one which will save again in cache.

Their two object of class name

  • obj->Old values,
  • obj1-> New values.

Recquried

  • obj3-> Final Output.

Old Values

class A{
 String name="abc";
String email="x@gmail.com";
String phone="123456789";
} 

New Values

class A{
 String name="xyz";
String email="";
} 

Want to update old values with new values only when their is some updated content in new values.

As in above case

  1. name is accepted as it changes
  2. email is not accepted as it is empty.
  3. Phone has no value so rejected.

Final output is:

class A
{
  String name="xyz";
    String email="x@gmail.com";
    String phone="123456789";
}

Is their any easy solution to make it simple

Rajesh Tiwari
  • 410
  • 5
  • 22
  • Jackson can update existing objects. Take a look at this answer which has a similar use case (patching an object): http://stackoverflow.com/questions/42976804/java-mapper-patcher-for-pojo/42977044#42977044 – john16384 Apr 01 '17 at 07:58
  • @john16384 Is this possible with GSON. currently using Retrofit with GSON – Rajesh Tiwari Apr 01 '17 at 08:32
  • I'm not sure if it is possible with GSON, you will have to investigate :) – john16384 Apr 01 '17 at 18:29

3 Answers3

1

Have you tried by defining a subclass of the BeanUtilsBean of the org.commons.beanutils package? Actually, BeanUtils uses this class.

Checking at the source code of that class, I think you can overwrite the copyProperty method, by checking for null values and doing nothing if the value is null.

Something like this :

package foo.bar.copy;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtilsBean;

public class NullAwareBeanUtilsBean extends BeanUtilsBean{

    @Override
    public void copyProperty(Object dest, String name, Object value)
            throws IllegalAccessException, InvocationTargetException {
    if(value==null || StringUtils.isEmpty(ObjectUtils.identityToString(value))) {
      return;
     }
        super.copyProperty(dest, name, value);
    }

}

Then you can just instantiate a NullAwareBeanUtilsBean and use it to copy your beans, for example:

BeanUtilsBean checkNullAnd=new NullAwareBeanUtilsBean();
checkNullAnd.copyProperties(dest, orig);

So, All this code will do is, it will check for null or Empty objects and not replace them with the old one.

ref : here

Community
  • 1
  • 1
Dave Ranjan
  • 2,966
  • 24
  • 55
0
You can make a get property to return the final class like so:

class A {
    String name  ="abc";
    String email ="x@gmail.com";
    String phone ="123456789";

   public A getFinalA(A a){
      if(a.name != null )  name  = (name == a.name ? name : a.name);
      if(a.email != null )  email= (email == a.email ? email : a.email);
      if(a.phone!= null )  phone= (phone== a.phone? phone: a.phone);

      A finalA = new A();
      A.name  = name;
      A.email = email;
      A.phone = phone;
   }
} 
Fady Saad
  • 1,169
  • 8
  • 13
0

Use below class to update only those values which are not null and use below method.

Coppier.copy(oldInstance, newInstance);

public class Coppier {
    private static final String GETTER_EXPRESSION = "(get)([A-Z]\\w+)";
    private static final String SETTER_EXPRESSION = "(set)([A-Z]\\w+)";
    private static final String SETTER_REPLACE_EXPRESSION = "set$2";
    private static final Pattern GETTER_PATTERN = Pattern.compile(GETTER_EXPRESSION);
    private static final Pattern SETTER_PATTERN = Pattern.compile(SETTER_EXPRESSION);

    private static void copy(Object from, Object to, Set<String> whitelist, Set<String> blacklist) {
        for (Method method : from.getClass().getDeclaredMethods()) {
            String name = method.getName();
            if (whitelist != null && !whitelist.contains(name)) {
                continue;
            }
            if (blacklist != null && blacklist.contains(name)) {
                continue;
            }
            if (Modifier.isPublic(method.getModifiers()) && isGetter(method)) {
                Method setter = getSetterForGetter(to, method);
                if (setter != null)
                    try {
                        String setterName = setter.getName();
                        if (!(setterName.equals("setWalletAmount") || setterName.equals("setId"))) {
                            Object product = method.invoke(from);
                            setter.invoke(to, product);
                        }
                    } catch (IllegalAccessException e) {
                    //
                    } catch (InvocationTargetException e) {
                    //
                    }
            }
        }
    }

    public static void copy(Object from, Object to) {
        copy(from, to, null, null);
    }

    private static boolean isGetter(Method method) {
        return isGetter(method.getName());
    }

    private static boolean isGetter(String methodName) {
        return GETTER_PATTERN.matcher(methodName).matches();
    }

    private static boolean isSetter(Method method) {
        return isSetter(method.getName());
    }

    private static boolean isSetter(String methodName) {
        return SETTER_PATTERN.matcher(methodName).matches();
    }

    private static String getSetterNameFromGetterName(String methodName) {
        return methodName.replaceFirst(GETTER_EXPRESSION, SETTER_REPLACE_EXPRESSION);
    }

    private static Method getSetterForGetter(Object instance, Method method) {
        String setterName = getSetterNameFromGetterName(method.getName());
        try {
            return instance.getClass().getMethod(setterName, method.getReturnType());
        } catch (NoSuchMethodException e) {
            return null;
        }
    }
}
Antoine C.
  • 3,730
  • 5
  • 32
  • 56
JeeVan TiWari
  • 325
  • 2
  • 15