001/* 002 * JDrupes Json-B plugins 003 * Copyright (C) 2024 Michael N. Lipp 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.jsonb.beans; 020 021import java.beans.BeanInfo; 022import java.beans.IntrospectionException; 023import java.beans.Introspector; 024import java.beans.PropertyEditor; 025import java.beans.PropertyEditorManager; 026import java.util.Collections; 027import java.util.Map; 028import java.util.WeakHashMap; 029 030/// Common base class for the JavaBean serializer and deserializer. 031public class JavaBeanConverter { 032 033 @SuppressWarnings({ "PMD.UseConcurrentHashMap", 034 "PMD.FieldNamingConventions", "PMD.VariableNamingConventions" }) 035 private static final Map<Class<?>, PropertyEditor> propertyEditorCache 036 = Collections.synchronizedMap(new WeakHashMap<>()); 037 @SuppressWarnings({ "PMD.UseConcurrentHashMap", 038 "PMD.FieldNamingConventions", "PMD.VariableNamingConventions" }) 039 private static final Map<Class<?>, BeanInfo> beanInfoCache 040 = Collections.synchronizedMap(new WeakHashMap<>()); 041 042 /// Find the property editor for the given class. 043 /// 044 /// @param cls the class 045 /// @return the property editor 046 protected static PropertyEditor findPropertyEditor(Class<?> cls) { 047 PropertyEditor propertyEditor = propertyEditorCache.get(cls); 048 if (propertyEditor == null && !propertyEditorCache.containsKey(cls)) { 049 // Never looked for before. 050 propertyEditor = PropertyEditorManager.findEditor(cls); 051 propertyEditorCache.put(cls, propertyEditor); 052 } 053 return propertyEditor; 054 } 055 056 /// Find the bean info for the given class. 057 /// 058 /// @param cls the class 059 /// @return the bean info 060 @SuppressWarnings("PMD.EmptyCatchBlock") 061 protected static BeanInfo findBeanInfo(Class<?> cls) { 062 BeanInfo beanInfo = beanInfoCache.get(cls); 063 if (beanInfo == null && !beanInfoCache.containsKey(cls)) { 064 try { 065 beanInfo = Introspector.getBeanInfo(cls, Object.class); 066 } catch (IntrospectionException e) { 067 // Bad luck 068 } 069 beanInfoCache.put(cls, beanInfo); 070 } 071 return beanInfo; 072 } 073 074 /// Create a new instance. 075 public JavaBeanConverter() { 076 // Can be instantiated. 077 } 078}