Package com.dooapp.gaedo.finders.root

Source Code of com.dooapp.gaedo.finders.root.ReflectionBackedInformer$AsFieldInformer

package com.dooapp.gaedo.finders.root;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.dooapp.gaedo.finders.FieldInformer;
import com.dooapp.gaedo.finders.FieldInformerAPI;
import com.dooapp.gaedo.finders.Informer;
import com.dooapp.gaedo.finders.QueryExpression;
import com.dooapp.gaedo.finders.expressions.EqualsExpression;
import com.dooapp.gaedo.properties.Property;
import com.dooapp.gaedo.properties.PropertyProvider;

public class ReflectionBackedInformer<DataType> implements Informer<DataType> {
  /**
   * Class used when a {@link ReflectionBackedInformer} is seen as a field of another object
   * @author ndx
   *
   */
  public class AsFieldInformer implements Informer<DataType> {
    /**
     * Field used to see the containing {@link ReflectionBackedInformer}
     */
    private Property field;
    /**
     * Stored parent path
     */
    private List<Property> parentPath = Collections.emptyList();

    public AsFieldInformer(Property field) {
      this.field = field;
    }

    @Override
    public FieldInformer get(String string, Collection<Property> propertyPath) {
      FieldInformer returned = ReflectionBackedInformer.this.get(string);
      if(returned instanceof FieldInformerAPI) {
        // Improve path with this informer one
        Collection<Property> newPath = new LinkedList<Property>(propertyPath);
        newPath.add(field);
        returned = ((FieldInformerAPI) returned).with(newPath);
      }
      return returned;
    }

    @Override
    public FieldInformer get(String string) {
      return get(string, parentPath);
    }

    @Override
    public QueryExpression equalsTo(Object value) {
      return new EqualsExpression(field, getFieldPath(), value);
    }

    @Override
    public Informer asField(Property field) {
      return ReflectionBackedInformer.this.asField(field);
    }

    @Override
    public Property getField() {
      return field;
    }

    @Override
    public Collection<FieldInformer> getAllFieldInformers() {
      return ReflectionBackedInformer.this.getAllFieldInformers();
    }

    @Override
    public Collection<Property> getAllFields() {
      return ReflectionBackedInformer.this.getAllFields();
    }

    @Override
    public Iterable<Property> getFieldPath() {
      List<Property> returned  = new LinkedList<Property>(parentPath);
      returned.add(field);
      return returned;
    }

    @Override
    public FieldInformer with(Collection<Property> propertyPath) {
      return new AsFieldInformer(field);
    }

    /**
     * @return
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + getOuterType().hashCode();
      result = prime * result + ((field == null) ? 0 : field.hashCode());
      return result;
    }

    /**
     * @param obj
     * @return
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      AsFieldInformer other = (AsFieldInformer) obj;
      if (!getOuterType().equals(other.getOuterType()))
        return false;
      if (field == null) {
        if (other.field != null)
          return false;
      } else if (!field.equals(other.field))
        return false;
      return true;
    }

    private ReflectionBackedInformer getOuterType() {
      return ReflectionBackedInformer.this;
    }
  }
 
  /**
   * Informer for super class
   */
  private Informer<? super DataType> parent;
 
  /**
   * Local class, used for getting fields and properties
   */
  private Class<DataType> clazz;
 
  private Map<Property, FieldInformer> fields = new HashMap<Property, FieldInformer>();
 
  private PropertyProvider propertyProvider;

  public ReflectionBackedInformer(Class<DataType> clazz,
      ReflectionBackedInformerFactory reflectionBackedInformerFactory,
      PropertyProvider provider) {
    // Immediatly load parent infos
    if(!clazz.isAssignableFrom(Object.class)) {
      parent = reflectionBackedInformerFactory.get(clazz.getSuperclass());
    }
    // Now, get all fields
    this.clazz = clazz;
    this.propertyProvider = provider;
    loadFieldsInformers(reflectionBackedInformerFactory);
  }

  /**
   * Load all fields informers from the class fields
   * @param reflectionBackedInformerFactory
   */
  private void loadFieldsInformers(ReflectionBackedInformerFactory reflectionBackedInformerFactory) {
    Property[] fieldsArray = propertyProvider.get(clazz);
    for(Property f : fieldsArray) {
      try {
        fields.put(f, reflectionBackedInformerFactory.getInformerFor(f));
      } catch(UnsupportedOperationException e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  public FieldInformer get(String string, Collection<Property> propertyPath) {
    FieldInformer returned = internalGet(string);
    if(returned instanceof FieldInformerAPI) {
      returned = ((FieldInformerAPI) returned).with(new LinkedList<Property>(propertyPath));
    }
    return returned;
  }

  @Override
  public FieldInformer get(String string) {
    return get(string, new LinkedList<Property>());
  }
 

  public FieldInformer internalGet(String string) {
    for(Map.Entry<Property, FieldInformer> f : fields.entrySet()) {
      if(f.getKey().getName().equals(string)) {
        return f.getValue();
      } else if((clazz.getSimpleName()+"."+f.getKey().getName()).equals(string)) {
        return f.getValue();
      }
    }
    if(parent!=null) {
      return parent.get(string);
    } else {
      throw new NoSuchFieldInHierarchyException(string);
    }
  }

  /**
   * The equalsTo method, as implemented by {@link Informer}, checks that the informer reference is equals to the reference given.
   * As a consequence, a null value is given for the field (which is an error since it does not allows model navigation)
   */
  @Override
  public QueryExpression equalsTo(Object value) {
    return new EqualsExpression(null, new LinkedList<Property>(), value);
  }

  @Override
  public Informer asField(Property field) {
    return new AsFieldInformer(field);
  }

  /**
   * There is no field associated with object informer. As a consequence, an exception is thrown
   */
  @Override
  public Property getField() {
    throw new UnsupportedOperationException("No field can be associated to a ReflectionBackedInformer, which only describes a root object");
  }

  /**
   * Get all fields of this object. This method creates a short lifetime collection containing all fields of this object (coming from this class and from superclass)
   * @return
   */
  public Collection<FieldInformer> getAllFieldInformers() {
    Collection<FieldInformer> toReturn = new LinkedList<FieldInformer>();
    if(parent!=null) {
      toReturn.addAll(parent.getAllFieldInformers());
    }
    toReturn.addAll(fields.values());
    return toReturn;
  }

  @Override
  public Collection<Property> getAllFields() {
    Collection<Property> toReturn = new LinkedList<Property>();
    if(parent!=null) {
      toReturn.addAll(parent.getAllFields());
    }
    toReturn.addAll(fields.keySet());
    return toReturn;
  }

  @Override
  public Iterable<Property> getFieldPath() {
    // TODO Auto-generated method stub
    throw new UnsupportedOperationException("method "+FieldInformer.class.getName()+"#getFieldPath has not yet been implemented AT ALL");
  }

  @Override
  public FieldInformer with(Collection<Property> propertyPath) {
    // TODO Auto-generated method stub
    throw new UnsupportedOperationException("method "+FieldInformerAPI.class.getName()+"#use has not yet been implemented AT ALL");
  }

  /**
   * @return
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
    return result;
  }

  /**
   * @param obj
   * @return
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    ReflectionBackedInformer other = (ReflectionBackedInformer) obj;
    if (clazz == null) {
      if (other.clazz != null)
        return false;
    } else if (!clazz.getCanonicalName().equals(other.clazz.getCanonicalName()))
      return false;
    return true;
  }
}
TOP

Related Classes of com.dooapp.gaedo.finders.root.ReflectionBackedInformer$AsFieldInformer

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.