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

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

// ***************************************************************************************************************************
// * 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 static org.apache.juneau.internal.CollectionUtils.*;
import static org.apache.juneau.internal.ObjectUtils.*;
import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.annotation.Bean;
import org.apache.juneau.collections.*;
import org.apache.juneau.marshaller.*;

/**
 * Utility class for comparing two versions of a POJO.
 *
 * 

* *

* // Two beans to compare. * MyBean bean1, bean2; * * // Get differences. * BeanDiff beanDiff = BeanDiff.create(bean1, bean2).exclude("fooProperty").build(); * * // Check for differences. * boolean hasDiff = beanDiff.hasDiffs(); * * JsonMap v1Diffs = beanDiff.getV1(); // Get version 1 differences. * JsonMap v2Diffs = beanDiff.getV2(); // Get version 2 differences. * * // Display differences. * System.err.println(beanDiff); *

* *
See Also:
    *
*/ @Bean(properties="v1,v2") public class BeanDiff { //----------------------------------------------------------------------------------------------------------------- // Static //----------------------------------------------------------------------------------------------------------------- /** * Create a new builder for this class. * * @param The bean types. * @param first The first bean to compare. * @param second The second bean to compare. * @return A new builder. */ public static Builder create(T first, T second) { return new Builder().first(first).second(second); } //----------------------------------------------------------------------------------------------------------------- // Builder //----------------------------------------------------------------------------------------------------------------- /** * Builder class. * * @param The bean type. */ public static class Builder { T first, second; BeanContext beanContext = BeanContext.DEFAULT; Set include, exclude; /** * Specifies the first bean to compare. * * @param value The first bean to compare. * @return This object. */ public Builder first(T value) { this.first = value; return this; } /** * Specifies the second bean to compare. * * @param value The first bean to compare. * @return This object. */ public Builder second(T value) { this.second = value; return this; } /** * Specifies the bean context to use for introspecting beans. * *

* If not specified, uses {@link BeanContext#DEFAULT}. * * @param value The bean context to use for introspecting beans. * @return This object. */ public Builder beanContext(BeanContext value) { this.beanContext = value; return this; } /** * Specifies the properties to include in the comparison. * *

* If not specified, compares all properties. * * @param properties The properties to include in the comparison. * @return This object. */ public Builder include(String...properties) { include = set(properties); return this; } /** * Specifies the properties to include in the comparison. * *

* If not specified, compares all properties. * * @param properties The properties to include in the comparison. * @return This object. */ public Builder include(Set properties) { include = properties; return this; } /** * Specifies the properties to exclude from the comparison. * * @param properties The properties to exclude from the comparison. * @return This object. */ public Builder exclude(String...properties) { exclude = set(properties); return this; } /** * Specifies the properties to exclude from the comparison. * * @param properties The properties to exclude from the comparison. * @return This object. */ public Builder exclude(Set properties) { exclude = properties; return this; } /** * Build the differences. * * @return A new {@link BeanDiff} object. */ public BeanDiff build() { return new BeanDiff(beanContext, first, second, include, exclude); } } //----------------------------------------------------------------------------------------------------------------- // Instance //----------------------------------------------------------------------------------------------------------------- private JsonMap v1 = new JsonMap(), v2 = new JsonMap(); /** * Constructor. * * @param The bean types. * @param bc The bean context to use for comparing beans. * @param first The first bean to compare. * @param second The second bean to compare. * @param include * Optional properties to include in the comparison. *
If null, all properties are included. * @param exclude * Optional properties to exclude in the comparison. *
If null, no properties are excluded. */ @SuppressWarnings("null") public BeanDiff(BeanContext bc, T first, T second, Set include, Set exclude) { if (first == null && second == null) return; BeanMap bm1 = first == null ? null : bc.toBeanMap(first); BeanMap bm2 = second == null ? null : bc.toBeanMap(second); Set keys = bm1 != null ? bm1.keySet() : bm2.keySet(); keys.forEach(k -> { if ((include == null || include.contains(k)) && (exclude == null || ! exclude.contains(k))) { Object o1 = bm1 == null ? null : bm1.get(k); Object o2 = bm2 == null ? null : bm2.get(k); if (ne(o1, o2)) { if (o1 != null) v1.put(k, o1); if (o2 != null) v2.put(k, o2); } } }); } /** * Returns true if the beans had differences. * * @return true if the beans had differences. */ public boolean hasDiffs() { return v1.size() > 0 || v2.size() > 0; } /** * Returns the differences in the first bean. * * @return The differences in the first bean. */ public JsonMap getV1() { return v1; } /** * Returns the differences in the second bean. * * @return The differences in the second bean. */ public JsonMap getV2() { return v2; } @Override public String toString() { return Json5.of(this); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy