public void populateWithProperties()

in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java [603:831]


   public void populateWithProperties(final Object target, final String propsId, Map<String, Object> beanProperties) throws InvocationTargetException, IllegalAccessException {
      CollectionAutoFillPropertiesUtil autoFillCollections = new CollectionAutoFillPropertiesUtil(getBrokerPropertiesRemoveValue(beanProperties));
      BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), autoFillCollections) {
         // override to treat missing properties as errors, not skip as the default impl does
         @Override
         public void setProperty(final Object bean, String name, final Object value) throws InvocationTargetException, IllegalAccessException {
            {
               if (logger.isDebugEnabled()) {
                  logger.debug("setProperty on {}, name: {}, value: {}", bean.getClass(), name, value);
               }
               // Resolve any nested expression to get the actual target bean
               Object target = bean;
               final Resolver resolver = getPropertyUtils().getResolver();
               while (resolver.hasNested(name)) {
                  try {
                     target = getPropertyUtils().getProperty(target, resolver.next(name));
                     if (target == null) {
                        throw new InvocationTargetException(null, "Resolved nested property for:" + name + ", on: " + bean + " was null");
                     }
                     name = resolver.remove(name);
                  } catch (final NoSuchMethodException e) {
                     throw new InvocationTargetException(e, "No getter for property:" + name + ", on: " + bean);
                  }
               }
               logger.trace("resolved target, bean: {}, name: {}", target.getClass(), name);

               final String propName = resolver.getProperty(name); // Simple name of target property
               if (autoFillCollections.isRemoveValue(value)) {
                  logger.trace("removing from target, bean: {}, name: {}", target.getClass(), name);

                  // we may do a further get but no longer want to reference our nested collection stack
                  if (!autoFillCollections.collections.isEmpty()) {
                     autoFillCollections.collections.pop();
                  }
                  if (target instanceof Map) {
                     Map targetMap = (Map) target;
                     Iterator<Map.Entry<String, Object>> i = targetMap.entrySet().iterator();
                     while (i.hasNext()) {
                        String key = i.next().getKey();
                        if (propName.equals(key)) {
                           i.remove();
                           break;
                        }
                     }
                  } else if (target instanceof Collection) {
                     try {
                        autoFillCollections.removeByNameProperty(propName, (Collection) target);
                     } catch (NoSuchMethodException e) {
                        throw new InvocationTargetException(e, "Can only remove named entries from collections or maps" + name + ", on: " + target);
                     }
                  } else {
                     throw new InvocationTargetException(null, "Can only remove entries from collections or maps" + name + ", on: " + target);
                  }

                  logger.trace("removed from target, bean: {}, name: {}", target.getClass(), name);
                  return;
               }

               Class<?> type = null;                         // Java type of target property
               final int index = resolver.getIndex(name);         // Indexed subscript value (if any)
               final String key = resolver.getKey(name);           // Mapped key value (if any)

               // Calculate the property type
               if (target instanceof DynaBean) {
                  throw new InvocationTargetException(null, "Cannot determine DynaBean type to access: " + name + " on: " + target);
               } else if (target instanceof Map) {
                  type = Object.class;
               } else if (target != null && target.getClass().isArray() && index >= 0) {
                  type = Array.get(target, index).getClass();
               } else {
                  PropertyDescriptor descriptor = null;
                  try {
                     descriptor = getPropertyUtils().getPropertyDescriptor(target, name);
                     if (descriptor == null) {
                        throw new InvocationTargetException(null, "No accessor method descriptor for: " + name + " on: " + target.getClass());
                     }
                  } catch (final NoSuchMethodException e) {
                     throw new InvocationTargetException(e, "Failed to get descriptor for: " + name + " on: " + target.getClass());
                  }
                  if (descriptor instanceof MappedPropertyDescriptor) {
                     if (((MappedPropertyDescriptor) descriptor).getMappedWriteMethod() == null) {
                        throw new InvocationTargetException(null, "No mapped Write method for: " + name + " on: " + target.getClass());
                     }
                     type = ((MappedPropertyDescriptor) descriptor).getMappedPropertyType();
                  } else if (index >= 0 && descriptor instanceof IndexedPropertyDescriptor) {
                     if (((IndexedPropertyDescriptor) descriptor).getIndexedWriteMethod() == null) {
                        throw new InvocationTargetException(null, "No indexed Write method for: " + name + " on: " + target.getClass());
                     }
                     type = ((IndexedPropertyDescriptor) descriptor).getIndexedPropertyType();
                  } else if (index >= 0 && List.class.isAssignableFrom(descriptor.getPropertyType())) {
                     type = Object.class;
                  } else if (key != null) {
                     if (descriptor.getReadMethod() == null) {
                        throw new InvocationTargetException(null, "No Read method for: " + name + " on: " + target.getClass());
                     }
                     type = (value == null) ? Object.class : value.getClass();
                  } else {
                     if (descriptor.getWriteMethod() == null) {
                        throw new InvocationTargetException(null, "No Write method for: " + name + " on: " + target.getClass());
                     }
                     type = descriptor.getPropertyType();
                  }
               }

               // Convert the specified value to the required type
               Object newValue = null;
               if (type.isArray() && (index < 0)) { // Scalar value into array
                  if (value == null) {
                     final String[] values = new String[1];
                     values[0] = null;
                     newValue = getConvertUtils().convert(values, type);
                  } else if (value instanceof String) {
                     newValue = getConvertUtils().convert(value, type);
                  } else if (value instanceof String[]) {
                     newValue = getConvertUtils().convert((String[]) value, type);
                  } else {
                     newValue = convert(value, type);
                  }
               } else if (type.isArray()) {         // Indexed value into array
                  if (value instanceof String || value == null) {
                     newValue = getConvertUtils().convert((String) value, type.getComponentType());
                  } else if (value instanceof String[]) {
                     newValue = getConvertUtils().convert(((String[]) value)[0], type.getComponentType());
                  } else {
                     newValue = convert(value, type.getComponentType());
                  }
               } else {                             // Value into scalar
                  if (value instanceof String) {
                     newValue = getConvertUtils().convert((String) value, type);
                  } else if (value instanceof String[]) {
                     newValue = getConvertUtils().convert(((String[]) value)[0], type);
                  } else {
                     newValue = convert(value, type);
                  }
               }

               // Invoke the setter method
               try {
                  getPropertyUtils().setProperty(target, name, newValue);
               } catch (final NoSuchMethodException e) {
                  throw new InvocationTargetException(e, "Cannot set: " + propName + " on: " + target.getClass());
               }
            }
         }
      };
      autoFillCollections.setBeanUtilsBean(beanUtils);
      // nested property keys delimited by . and enclosed by '"' if they key's themselves contain dots
      beanUtils.getPropertyUtils().setResolver(new SurroundResolver(getBrokerPropertiesKeySurround(beanProperties)));
      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            return (T) SimpleString.toSimpleString(value.toString());
         }
      }, SimpleString.class);

      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            NamedPropertyConfiguration instance = new NamedPropertyConfiguration();
            instance.setName(value.toString());
            instance.setProperties(new HashMap<>());
            return (T) instance;
         }
      }, NamedPropertyConfiguration.class);

      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            TransformerConfiguration instance = new TransformerConfiguration(value.toString());
            return (T) instance;
         }
      }, TransformerConfiguration.class);

      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            List convertedValue = new ArrayList<String>();
            for (String entry : value.toString().split(",")) {
               convertedValue.add(entry);
            }
            return (T) convertedValue;
         }
      }, java.util.List.class);

      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            Set convertedValue = new HashSet();
            for (String entry : value.toString().split(",")) {
               convertedValue.add(entry);
            }
            return (T) convertedValue;
         }
      }, java.util.Set.class);

      // support 25K or 25m etc like xml config
      beanUtils.getConvertUtils().register(new Converter() {
         @Override
         public <T> T convert(Class<T> type, Object value) {
            return (T) (Long) ByteUtil.convertTextBytes(value.toString());
         }
      }, Long.TYPE);

      BeanSupport.customise(beanUtils);

      logger.trace("populate: bean: {} with {}", this, beanProperties);

      HashMap<String, String> errors = new HashMap<>();
      // Loop through the property name/value pairs to be set
      for (final Map.Entry<String, ? extends Object> entry : beanProperties.entrySet()) {
         // Identify the property name and value(s) to be assigned
         final String name = entry.getKey();
         try {
            // Perform the assignment for this property
            beanUtils.setProperty(target, name, entry.getValue());
         } catch (InvocationTargetException invocationTargetException) {
            logger.trace("failed to populate property with key: {}", name, invocationTargetException);
            Throwable toLog = invocationTargetException;
            if (invocationTargetException.getCause() != null) {
               toLog = invocationTargetException.getCause();
            }
            trackError(errors, entry, toLog);

         } catch (Exception oops) {
            trackError(errors, entry, oops);
         }
      }
      updateApplyStatus(propsId, errors);
   }