
001/*- 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2025 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.util; 021 022import org.hl7.fhir.instance.model.api.IPrimitiveType; 023 024import java.lang.reflect.Field; 025import java.util.function.BiPredicate; 026 027/** 028 * Boolean-value function for comparing two FHIR primitives via <code>.equals()</code> method on the instance 029 * internal values. 030 */ 031public class PrimitiveTypeEqualsPredicate implements BiPredicate { 032 033 /** 034 * Returns true if both bases are of the same type and hold the same values. 035 */ 036 @Override 037 public boolean test(Object theBase1, Object theBase2) { 038 if (theBase1 == null) { 039 return theBase2 == null; 040 } 041 if (theBase2 == null) { 042 return false; 043 } 044 if (!theBase1.getClass().equals(theBase2.getClass())) { 045 return false; 046 } 047 048 for (Field f : theBase1.getClass().getDeclaredFields()) { 049 Class<?> fieldClass = f.getType(); 050 051 if (!IPrimitiveType.class.isAssignableFrom(fieldClass)) { 052 continue; 053 } 054 055 IPrimitiveType<?> val1, val2; 056 057 f.setAccessible(true); 058 try { 059 val1 = (IPrimitiveType<?>) f.get(theBase1); 060 val2 = (IPrimitiveType<?>) f.get(theBase2); 061 } catch (Exception e) { 062 // swallow 063 continue; 064 } 065 066 if (val1 == null && val2 == null) { 067 continue; 068 } 069 070 if (val1 == null || val2 == null) { 071 return false; 072 } 073 074 Object actualVal1 = val1.getValue(); 075 Object actualVal2 = val2.getValue(); 076 077 if (actualVal1 == null && actualVal2 == null) { 078 continue; 079 } 080 if (actualVal1 == null) { 081 return false; 082 } 083 if (!actualVal1.equals(actualVal2)) { 084 return false; 085 } 086 } 087 088 return true; 089 } 090}