public BeanMapper()

in firebase-database/src/main/java/com/google/firebase/database/core/utilities/encoding/CustomClassMapper.java [452:550]


    public BeanMapper(Class<T> clazz) {
      this.clazz = clazz;
      this.throwOnUnknownProperties = clazz.isAnnotationPresent(ThrowOnExtraProperties.class);
      this.warnOnUnknownProperties = !clazz.isAnnotationPresent(IgnoreExtraProperties.class);
      this.properties = new HashMap<>();

      this.setters = new HashMap<>();
      this.getters = new HashMap<>();
      this.fields = new HashMap<>();

      Constructor<T> constructor = null;
      try {
        constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
      } catch (NoSuchMethodException e) {
        // We will only fail at deserialization time if no constructor is present
        constructor = null;
      }
      this.constructor = constructor;
      // Add any public getters to properties (including isXyz())
      for (Method method : clazz.getMethods()) {
        if (shouldIncludeGetter(method)) {
          String propertyName = propertyName(method);
          addProperty(propertyName);
          method.setAccessible(true);
          if (getters.containsKey(propertyName)) {
            throw new DatabaseException("Found conflicting getters for name: " + method.getName());
          }
          getters.put(propertyName, method);
        }
      }

      // Add any public fields to properties
      for (Field field : clazz.getFields()) {
        if (shouldIncludeField(field)) {
          String propertyName = propertyName(field);

          addProperty(propertyName);
        }
      }

      // We can use private setters and fields for known (public) properties/getters. Since
      // getMethods/getFields only returns public methods/fields we need to traverse the
      // class hierarchy to find the appropriate setter or field.
      Class<? super T> currentClass = clazz;
      do {
        // Add any setters
        for (Method method : currentClass.getDeclaredMethods()) {
          if (shouldIncludeSetter(method)) {
            String propertyName = propertyName(method);
            String existingPropertyName = properties.get(propertyName.toLowerCase(Locale.US));
            if (existingPropertyName != null) {
              if (!existingPropertyName.equals(propertyName)) {
                throw new DatabaseException(
                    "Found setter with invalid " + "case-sensitive name: " + method.getName());
              } else {
                Method existingSetter = setters.get(propertyName);
                if (existingSetter == null) {
                  method.setAccessible(true);
                  setters.put(propertyName, method);
                } else if (!isSetterOverride(method, existingSetter)) {
                  // We require that setters with conflicting property names are
                  // overrides from a base class
                  throw new DatabaseException(
                      "Found a conflicting setters "
                          + "with name: "
                          + method.getName()
                          + " (conflicts with "
                          + existingSetter.getName()
                          + " defined on "
                          + existingSetter.getDeclaringClass().getName()
                          + ")");
                }
              }
            }
          }
        }

        for (Field field : currentClass.getDeclaredFields()) {
          String propertyName = propertyName(field);

          // Case sensitivity is checked at deserialization time
          // Fields are only added if they don't exist on a subclass
          if (properties.containsKey(propertyName.toLowerCase(Locale.US))
              && !fields.containsKey(propertyName)) {
            field.setAccessible(true);
            fields.put(propertyName, field);
          }
        }

        // Traverse class hierarchy until we reach java.lang.Object which contains a bunch
        // of fields/getters we don't want to serialize
        currentClass = currentClass.getSuperclass();
      } while (currentClass != null && !currentClass.equals(Object.class));

      if (properties.isEmpty()) {
        throw new DatabaseException("No properties to serialize found on class " + clazz.getName());
      }
    }