All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.ui.autoui.api.BeanValueProvider Maven / Gradle / Ivy

The newest version!
package xapi.ui.autoui.api;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import xapi.collect.api.StringTo;
import xapi.collect.impl.ArrayIterable;
import xapi.source.write.MappedTemplate;
import xapi.util.api.ConvertsValue;

public class BeanValueProvider {

  private static Object getValue(String name, Object object, Map> map) {
    if (!map.containsKey(name)){
      illegalArg(name);
    }
    return map.get(name).convert(object);
  }

  protected static Object illegalArg(String name) {
    throw new IllegalArgumentException("Value for field named "+name+" not found");
  }

  private class Converter {
    protected Object valueOf(String name, Object object) {
      return BeanValueProvider.this.valueOf(name, object);
    }
  }

  private class RebasedBeanValueProvider extends BeanValueProvider {
    private final String name;
    private final Converter converter;

    public RebasedBeanValueProvider(String name, Converter converter) {
      this.name = name;
      this.converter = converter;
    }

    @Override
    public Object getValue(String name, String context, Object object) {
//      assert context.equals(this.name);
      if ("$name".equals(name) || "this.name()".equals(name) || (this.name+".name()").equals(name))
        return this.name;
      if ("$value".equals(name) || "this".equals(name) || this.name.equals(name))
        return converter.valueOf(this.name, object);
      return converter.valueOf(this.name+"."+name, object);
    }
  }
  private class RebaseAllBeanValueProvider extends BeanValueProvider {

    private final Converter converter;

    private RebaseAllBeanValueProvider(Converter converter) {
      this.converter = converter;
    }

    @Override
    public Object getValue(String name, String context, Object object) {
      if ("$name".equals(name) || "this.name()".equals(name))
        return context;
      if ("$value".equals(name) || "this".equals(name))
        return object;
      if (context.length()>0) {
        context += ".";
      }
      return converter.valueOf(context+name, object);
    }

  }

  private Map> map = new LinkedHashMap>();
  private String[] childKeys;

  public void addProvider(String key, final String name, ConvertsValue provider) {
    map.put(key, provider);
    ConvertsValue namer = new ConvertsValue() {
      @Override
      public Object convert(Object from) {
        return from instanceof HasName ? ((HasName)from).getName() : name;
      }
    };
    map.put(key+".name()", namer );
    if ("this".equals(key)) {
      map.put("$name", namer);
      map.put("$value", provider);
    }
  }

  protected Object valueOf(String name, Object object) {
    return getValue(name, object, map);
  }

  protected String[] getKeys(Map> map) {
    String[] keys = map.keySet().toArray(new String[map.size()]);
    for (int i = keys.length; i-->0;) {
      keys[i] = "${"+keys[i]+"}";
    }
    return keys;
  }

  protected String[] childKeys() {
    if (childKeys == null) {
      List keys = new ArrayList();
      for (Entry> entry : map.entrySet()) {
        String key = entry.getKey();
        if (key.indexOf('.') == -1 && !"this".equals(key)) {
          keys.add(key);
        }
      }
      childKeys = keys.toArray(new String[keys.size()]);
    }
    return childKeys;
  }

  public void setChildKeys(String[] keys) {
    this.childKeys = keys;
  }

  public Object getValue(String name, String context, Object object) {
    return valueOf(name, object);
  }

  public BeanValueProvider rebase(String methodName) {
    BeanValueProvider bean = new RebasedBeanValueProvider(methodName, new Converter());
    bean.childKeys = childKeys;
    bean.map = map;
    return bean;
  }

  public BeanValueProvider rebaseAll() {
    BeanValueProvider bean = new RebaseAllBeanValueProvider(new Converter());
    bean.childKeys = childKeys;
    bean.map = map;
    return bean;
  }

  public Iterable getChildKeys() {
    return new ArrayIterable(childKeys());
  }

  @SuppressWarnings({
      "rawtypes", "unchecked"
  })
  public void fillMap(String name, MappedTemplate template, StringTo map, Object val) {
    if ("".equals(name)) {
      for (String key : childKeys()) {
        String k = key.startsWith("$") ? key : "${"+key+"}";
        if (template.hasKey(k)) {
          map.put(k, getValue(key, "", val));
        }
        k = "${"+key+".name()}";
        if (template.hasKey(k)) {
          map.put(k, key);
        }
      }
    } else {
      val = getValue(name, "", val);
      map.put("$value", val);
      map.put("$name", name);
      map.put("${"+name+"}", val);
      map.put("${"+name+".name()}", name);
      // We should also have a means to do deep name resolving on rebased bean items...
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy