Package main.settings.reflect

Source Code of main.settings.reflect.AbstractSettingsContainerReflector

package main.settings.reflect;


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Properties;
import java.util.Set;

import misc.Mask;


public abstract class AbstractSettingsContainerReflector
{
  private SettingsContainer container;
  private String path;

  protected AbstractSettingsContainerReflector(SettingsContainer container, String path)
  {
    this.container = container;
    this.path = path;
  }

  protected AbstractSettingsContainerReflector(SettingsContainer container)
  {
    this(container, null);
  }

  public void fetchProperties(Properties properties)
  {
    Set<Object> settings = properties.keySet();
    for (Object setting : settings)
    {
      String settingName = setting.toString();
      tryToSet(settingName, properties.getProperty(settingName));
    }
  }

  private void tryToSet(String name, String value)
  {
    String[] path = name.split("\\.");
    try
    {
      findAndSet(path, value);
    }
    catch (Exception e)
    {
      System.err.println("errors in settings.ini: " + name);
    }
  }

  private void findAndSet(String[] path, String value) throws Exception
  {
    Field field = getField(path[0]);
    if (isContainer(field))
    {
      SettingsContainer container = SettingsContainer.class.cast(field
          .get(this.container));
      AbstractSettingsContainerReflector containerReflector = new SettingsContainerReflector(
          container);

      String[] childPath = Arrays.copyOfRange(path, 1, path.length);
      containerReflector.findAndSet(childPath, value);
    }
    else
    {
      setField(field, value);
    }
  }

  protected abstract Field getField(String name) throws Exception;

  private void setField(Field field, String value) throws Exception
  {
    Class<?> fieldType = field.getType();
    if (fieldType.isArray())
    {
      throw new NoSuchFieldException();
    }
    else if (fieldType.isPrimitive())
    {
      setPrimitiveField(field, fieldType, value);
    }
    else if (fieldType.equals(String.class))
    {
      field.set(container, value);
    }
    else
    {
      throw new NoSuchFieldException();
    }
  }

  private void setPrimitiveField(Field field, Class<?> fieldType, String value)
      throws IllegalArgumentException, Exception
  {
    if (fieldType.equals(Boolean.TYPE))
    {
      field.setBoolean(container, new Boolean(value));
    }
    else if (fieldType.equals(Character.TYPE))
    {
      field.setChar(container, new Character(value.charAt(0)));
    }
    else if (fieldType.equals(Byte.TYPE))
    {
      field.setByte(container, new Byte(value));
    }
    else if (fieldType.equals(Short.TYPE))
    {
      field.setShort(container, new Short(value));
    }
    else if (fieldType.equals(Integer.TYPE))
    {
      field.setInt(container, new Integer(value));
    }
    else if (fieldType.equals(Long.TYPE))
    {
      field.setLong(container, new Long(value));
    }
    else if (fieldType.equals(Float.TYPE))
    {
      field.setFloat(container, new Float(value));
    }
    else if (fieldType.equals(Double.TYPE))
    {
      field.setDouble(container, new Double(value));
    }
  }

  public void translateContainer(Properties properties)
  {
    Field[] fields = getFields();
    for (Field field : fields)
    {
      try
      {
        translateField(field, properties);
      }
      catch (Exception e)
      {
        continue;
      }
    }
  }

  protected abstract Field[] getFields();

  protected final SettingsContainer getContainer()
  {
    return container;
  }

  private void translateField(Field field, Properties properties) throws Exception
  {
    if (isContainer(field))
    {
      SettingsContainer subContainer = SettingsContainer.class.cast(field
          .get(container));
      String subContainerPath = getFieldPath(field);

      AbstractSettingsContainerReflector subContainerReflector = new SettingsContainerReflector(
          subContainer, subContainerPath);
      subContainerReflector.translateContainer(properties);
    }
    else
    {
      translateSimpleField(field, properties);
    }
  }

  private static boolean isContainer(Field field)
  {
    return SettingsContainer.class.isAssignableFrom(field.getType());
  }

  private void translateSimpleField(Field field, Properties properties)
      throws Exception
  {
    Mask modifiersMask = new Mask(field.getModifiers());
    if (!modifiersMask.contains(Modifier.FINAL))
    {
      String key = getFieldPath(field);
      String value = field.get(container).toString();
      properties.setProperty(key, value);
    }
  }

  private String getFieldPath(Field field)
  {
    if (path.equals(""))
    {
      return field.getName();
    }
    else
    {
      return path + "." + field.getName();
    }
  }

}
TOP

Related Classes of main.settings.reflect.AbstractSettingsContainerReflector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.