All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.utils.PojoMerge Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.utils;

import java.lang.reflect.*;

/**
 * Utility class for merging POJOs behind a single interface.
 *
 * 

* Useful in cases where you want to define beans with 'default' values. * *

* For example, given the following bean classes... * *

* public interface IA { * String getX(); * void setX(String x); * } * * public class A implements IA { * private String x; * * public A(String x) { * this.x = x; * } * * public String getX() { * return x; * } * * public void setX(String x) { * this.x = x; * } * } *

* *

* The getters will be called in order until the first non-null value is returned... * *

* PojoMerge m; * * m = PojoMerge.merge(IA.class, new A("1"), new A("2")); * assertEquals("1", m.getX()); * * m = PojoMerge.merge(IA.class, new A(null), new A("2")); * assertEquals("2", m.getX()); * * m = PojoMerge.merge(IA.class, new A(null), new A(null)); * assertEquals(null, m.getX()); *

* *
Notes:
*
    *
  • Null POJOs are ignored. *
  • Non-getter methods are either invoked on the first POJO or all POJOs depending on the callAllNonGetters flag * passed into the constructor. *
  • For purposes of this interface, a getter is any method with zero arguments and a non-void return type. *
*/ public class PojoMerge { /** * Create a proxy interface on top of zero or more POJOs. * *

* This is a shortcut to calling merge(interfaceClass, false, pojos); * * @param interfaceClass The common interface class. * @param pojos * Zero or more POJOs to merge. *
Can contain nulls. * @return A proxy interface over the merged POJOs. */ @SuppressWarnings("unchecked") public static T merge(Class interfaceClass, T...pojos) { return merge(interfaceClass, false, pojos); } /** * Create a proxy interface on top of zero or more POJOs. * * @param interfaceClass The common interface class. * @param callAllNonGetters * If true, when calling a method that's not a getter, the method will be invoked on all POJOs. *
Otherwise, the method will only be called on the first POJO. * @param pojos * Zero or more POJOs to merge. *
Can contain nulls. * @return A proxy interface over the merged POJOs. */ @SuppressWarnings("unchecked") public static T merge(Class interfaceClass, boolean callAllNonGetters, T...pojos) { return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] { interfaceClass }, new PojoMergeInvocationHandler(callAllNonGetters, pojos)); } private static class PojoMergeInvocationHandler implements InvocationHandler { private final Object[] pojos; private final boolean callAllNonGetters; public PojoMergeInvocationHandler(boolean callAllNonGetters, Object...pojos) { this.callAllNonGetters = callAllNonGetters; this.pojos = pojos; } /** * Implemented to handle the method called. * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */ @Override /* InvocationHandler */ public Object invoke(Object proxy, Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { Object r = null; boolean isGetter = args == null && method.getReturnType() != Void.class; for (Object pojo : pojos) { if (pojo != null) { r = method.invoke(pojo, args); if (isGetter) { if (r != null) return r; } else { if (! callAllNonGetters) return r; } } } return r; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy