/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI 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.openengsb.core.util; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.ReflectionUtils; import com.google.common.collect.Maps; /** * Provides utility-methods for converting beans to something that can be stored (Map) and vice versa. It uses * {@link BeanUtils} to provide that functionality. */ public final class BeanUtilsExtended { private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtilsExtended.class); /** * Analyzes the bean and returns a map containing the property-values. Works similar to * {@link BeanUtils#describe(Object)} but does not convert everything to strings. * * @throws IllegalArgumentException if the bean cannot be analyzed properly. Probably because some getter throw an * Exception */ public static Map<String, Object> buildObjectAttributeMap(Object bean) throws IllegalArgumentException { BeanInfo beanInfo; try { beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class); } catch (IntrospectionException e1) { throw new IllegalArgumentException(e1); } Map<String, Object> result; result = Maps.newHashMap(); for (PropertyDescriptor pDesc : beanInfo.getPropertyDescriptors()) { String name = pDesc.getName(); Object propertyValue; try { propertyValue = pDesc.getReadMethod().invoke(bean); } catch (IllegalAccessException e) { // this should never happen since the Introspector only returns accessible read-methods LOGGER.error("WTF: got property descriptor with inaccessible read-method"); throw new IllegalStateException(e); } catch (InvocationTargetException e) { ReflectionUtils.handleInvocationTargetException(e); throw new IllegalStateException("Should never get here"); } if (propertyValue != null) { result.put(name, propertyValue); } } return result; } /** * Creates a new instance of the beanType and populates it with the property-values from the map * * @throws IllegalArgumentException if the bean cannot be populated because of errors in the definition of the * beantype */ public static <BeanType> BeanType createBeanFromAttributeMap(Class<BeanType> beanType, Map<String, ? extends Object> attributeValues) { BeanType instance; try { instance = beanType.newInstance(); BeanUtils.populate(instance, attributeValues); } catch (Exception e) { ReflectionUtils.handleReflectionException(e); throw new IllegalStateException("Should never get here"); } return instance; } /** * returns the result of {@link BeanUtils#describe(Object)} converted to the proper generic map-type. * * Exceptions from Reflection are wrapped in {@link IllegalArgumentException}s * * @throws IllegalArgumentException if some property in the bean cannot be accessed */ @SuppressWarnings("unchecked") public static Map<String, String> buildStringAttributeMap(Object bean) throws IllegalArgumentException { try { return BeanUtils.describe(bean); } catch (Exception e) { ReflectionUtils.handleReflectionException(e); throw new IllegalStateException("Should never get here"); } } private BeanUtilsExtended() { } }