Package org.molgenis.model.elements

Source Code of org.molgenis.model.elements.Field

/**
* File: invengine_generate/meta/Field.java <br>
* Copyright: Inventory 2000-2006, GBIC 2005, all rights reserved <br>
* Changelog:
* <ul>
* <li>2005-12-06; 1.0.0; RA Scheltema; Creation.
* <li> 2006-01-11; 1.0.0; RA Scheltema; Added documentation.
* </ul>
*/
package org.molgenis.model.elements;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.molgenis.fieldtypes.CharField;
import org.molgenis.fieldtypes.EnumField;
import org.molgenis.fieldtypes.FieldType;
import org.molgenis.fieldtypes.MrefField;
import org.molgenis.fieldtypes.StringField;
import org.molgenis.fieldtypes.XrefField;
import org.molgenis.framework.db.DatabaseException;
import org.molgenis.generators.GeneratorHelper;
import org.molgenis.model.MolgenisModelException;
import org.molgenis.util.SimpleTree;
import org.molgenis.util.Tree;

/**
* Describes a field in an entity.
*
* @author RA Scheltema
* @author MA Swertz
* @version 1.0.0
*/
public class Field implements Serializable
{
  public static final String TYPE_FIELD = "__Type";
  /** Fixed value used for determining the not-set value for the varchar. */
  private static final int LENGTH_NOT_SET = 0;

  public Field(Entity parent, String name, FieldType type)
  {
    this(parent, type, name, name, false, false, false, null, null);
  }

  // constructor(s)
  /**
   * Standard constructor, which sets all the common variables for a field.
   * Extra fields can be set with the appropriate access methods.
   *
   * @param type
   *            The type of the field.
   * @param name
   *            The name of the field, which needs to be unique for the
   *            entity.
   * @param label
   *            The label of the field, which is used for the user interface.
   * @param auto
   *            Indicates whether this field needs to assigned a value by the
   *            database.
   * @param nillable
   *            Indicates whether this field can have the value NULL in the
   *            database.
   * @param readonly
   *            Indicates whether this field is readonly.
   * @param jpaCascade
   *            Makes it possible to use JPA Cascade options to streamline
   *            object datbase interaction, see JPA documentation for details
   */
  public Field(Entity parent, FieldType type, String name, String label, boolean auto, boolean nillable,
      boolean readonly, String default_value, String jpaCascade)
  {
    this.entity = parent;

    // global
    this.type = type;

    this.name = name;
    this.label = label;
    this.auto = auto;
    this.nillable = nillable;
    this.readonly = readonly;
    this.default_value = default_value;
    this.description = "";
    this.default_code = "";

    // varchar
    this.varchar_length = LENGTH_NOT_SET;

    // xref
    this.xref_entity = "";
    this.xref_field = "";
    this.xref_labels = new ArrayList<String>();

    //
    this.system = false;
    this.user_data = null;

    this.jpaCascade = jpaCascade;
  }

  public Field(String name)
  {
    this.name = name;
    this.type = new StringField();
  }

  // constructor(s)
  /**
   * Standard constructor, which sets all the common variables for a field.
   * Extra fields can be set with the appropriate access methods.
   *
   * @param type
   *            The type of the field.
   * @param name
   *            The name of the field, which needs to be unique for the
   *            entity.
   * @param label
   *            The label of the field, which is used for the user interface.
   * @param auto
   *            Indicates whether this field needs to assigned a value by the
   *            database.
   * @param nillable
   *            Indicates whether this field can have the value NULL in the
   *            database.
   * @param readonly
   *            Indicates whether this field is readonly.
   */
  public Field(Entity parent, FieldType type, String name, String label, boolean auto, boolean nillable,
      boolean readonly, String default_value)
  {
    this(parent, type, name, label, auto, nillable, readonly, default_value, null);
  }

  /**
   * copy-constructor
   */
  public Field(Field field)
  {
    this.auto = field.auto;
    this.default_code = field.default_code;
    this.default_value = field.default_value;
    this.description = field.description;
    this.entity = field.entity;
    this.enum_options = field.enum_options;
    this.filter = field.filter;
    this.filterfield = field.filterfield;
    this.filtertype = field.filtertype;
    this.filtervalue = field.filtervalue;
    this.hidden = field.hidden;
    this.label = field.label;
    this.mref_name = field.mref_name;
    this.mref_localid = field.mref_localid;
    this.mref_remoteid = field.mref_remoteid;
    this.name = field.name;
    this.nillable = field.nillable;
    this.readonly = field.readonly;
    this.system = field.system;
    this.type = field.type;
    this.user_data = field.user_data;
    this.varchar_length = field.varchar_length;
    this.xref_field = field.xref_field;
    this.xref_labels = field.xref_labels;
    this.xref_entity = field.xref_entity;
  }

  // global access methods
  /**
     *
     */
  @Deprecated
  public Entity getParent()
  {
    return entity;
  }

  public Entity getEntity()
  {
    return entity;
  }

  /**
   * This method returns the type of this field.
   *
   * @return The type of this field.
   */
  public FieldType getType()
  {
    return this.type;
  }

  /**
   * @param type
   */
  public void setType(FieldType type)
  {
    this.type = type;
  }

  public String getFormatString()
  {
    if (type instanceof XrefField || type instanceof MrefField)
    {
      try
      {
        return this.getXrefField().getFormatString();
      }
      catch (Exception e)
      {
        ;
      }
    }

    return type.getFormatString();
  }

  /**
   * This method returns the name of this field.
   *
   * @return The name of this field.
   */
  public String getName()
  {
    return this.name;
  }

  /**
     *
     */
  public void setName(String name)
  {
    this.name = name;
  }

  /**
   * This method returns the label of this field.
   *
   * @return The label of this field.
   */
  public String getLabel()
  {
    if (label == null)
    {
      return getName();
    }
    return this.label;
  }

  /**
     *
     */
  public void setLabel(String label)
  {
    this.label = label;
  }

  public void setAuto(boolean auto)
  {
    this.auto = auto;
  }

  /**
   * Returns whether this field is auto-assigned by the database.
   *
   * @return True when this field is auto-assigned, false otherwise.
   */
  public boolean isAuto()
  {
    return this.auto;
  }

  /**
   * Returns whether this field can be NULL in the database.
   *
   * @return True when this field can be NULL, false otherwise.
   */
  public boolean isNillable()
  {
    return this.nillable;
  }

  public void setReadonly(boolean readonly)
  {
    this.readonly = readonly;
  }

  public boolean isHidden()
  {
    return hidden;
  }

  public void setHidden(boolean hidden)
  {
    this.hidden = hidden;
  }

  /**
   * Returns whether this field is read-only in the database.
   *
   * @return True when this field is read-only, false otherwise.
   */
  public boolean isReadOnly()
  {
    return this.readonly;
  }

  /**
   * Returns whether this field is a system-field. When it is a system-field,
   * it will not be displayed in the user-interface.
   *
   * @return True when this field is a system-field, false otherwise.
   */
  public boolean isSystem()
  {
    return this.system;
  }

  /**
   * With this set-function the system-property can be set.
   *
   * @param s
   *            The system boolean.
   */
  public void setSystem(boolean s)
  {
    this.system = s;
  }

  /**
   * Returns whether this field is locally available in the table, or whether
   * it is located in another table (for example link-table).
   *
   * @return Whether this field is located in the table
   */
  public boolean isLocal()
  {
    return this.type instanceof MrefField;
  }

  /**
   * @throws MolgenisModelException
   *
   */
  public boolean isCyclic() throws MolgenisModelException
  {
    if (!(this.type instanceof XrefField))
    {
      return false;
    }

    if (xref_entity.equals(this.name))
    {
      return true;
    }

    DBSchema root = entity.getRoot();
    Entity e = (Entity) root.get(xref_entity);
    for (Field field : e.getAllFields())
    {
      if (!(field.type instanceof XrefField))
      {
        continue;
      }

      if (field.xref_entity.equals(this.name))
      {
        return true;
      }
    }

    return false;
  }

  /**
   * Returns whether this field is a xref.
   *
   * @return Whether this field is a xref.
   */
  // FIXME rename to isXref
  public boolean isXRef()
  {
    return type instanceof XrefField || type instanceof MrefField;
  }

  /**
   * Returns whether this field is a mref.
   *
   * @return Whether this field is a mref.
   */
  // FIXME rename to isMref
  public boolean isMRef()
  {
    return type instanceof MrefField;
  }

  /**
   * Returns the value the database should set for the field when there is no
   * value set.
   *
   * @return The default-value.
   */
  public String getDefaultValue()
  {
    return this.default_value;
  }

  // FIXME correct typo in method name (v --> f)
  public void setDevaultValue(String value)
  {
    this.default_value = value;
  }

  /**
   * Returns the description of the entity.
   *
   * @return The description.
   */
  public String getDescription()
  {
    return this.description;
  }

  /**
   * Sets the description of this entity.
   */
  public void setDescription(String description)
  {
    this.description = description;
  }

  // enum access methods
  /**
     *
     */
  public void setEnumOptions(Vector<String> options)
  {
    this.enum_options = options;
  }

  /**
     *
     */
  public Vector<String> getEnumOptions() throws MolgenisModelException
  {
    if (!(this.type instanceof EnumField))
    {
      throw new MolgenisModelException("Field is not a ENUM, so options cannot be set.");
    }

    return this.enum_options;
  }

  // varchar access methods
  /**
   * When this field is of type Type.VARCHAR, this method sets the maximum
   * length the varchar can be. When this field is not of type Type.VARCHAR,
   * this method raises an exception.
   *
   * @param length
   *            The maximum length the varchar field can be.
   * @throws Exception
   *             When the field is not of type Type.VARCHAR.
   */
  public void setVarCharLength(int length) // throws Exception
  {
    // if (this.type != Type.VARCHAR)
    // {
    // / throw new Exception("Field is not a VARCHAR, so length cannot be
    // set.");
    // }

    this.varchar_length = length;
  }

  /**
   * When this field is of type Type.VARCHAR, this method returns the maximum
   * length the varchar can be. When this field is not of type Type.VARCHAR,
   * this method raises an exception.
   *
   * @return The maximum length the varchar field can be.
   * @throws Exception
   *             When the field is not of type Type.VARCHAR.
   */
  public int getVarCharLength() throws MolgenisModelException
  {
    if (!(this.type instanceof StringField) && !(this.type instanceof CharField))
    {
      throw new MolgenisModelException("Field is not a VARCHAR, so length cannot be retrieved.");
    }

    return this.varchar_length;
  }

  // xref access methods
  // FIXME rename setXRefEntity to setXrefEntityName (R --> r, +Name)
  public void setXRefEntity(String xref_entity)
  {
    this.xref_entity = xref_entity;
  }

  /**
   * With this method all the additional information for this xref-field can
   * be set. When this field is not of type Type.XREF_SINGLE or
   * Type.XREF_MULTIPLE an exception is raised.
   *
   * @param entity
   *            The entity this field references.
   * @param field
   *            The field of the entity this field references.
   * @param label
   *            The label of this xref.
   * @throws Exception
   *             When this field is not of type Type.XREF_SINGLE or
   *             Type.XREF_MULTIPLE
   */
  // FIXME rename setXRefVariables to setXrefVariables
  public void setXRefVariables(String entity, String field, List<String> labels)
  {
    this.xref_entity = entity;
    this.xref_field = field;
    this.xref_labels = labels;
  }

  /**
   * Returns the name of the entity this field is referencing to. When this
   * field is not of type Type.XREF_SINGLE or Type.XREF_MULTIPLE an exception
   * is raised.
   *
   * @return The name of the entity this field is referencing.
   * @throws Exception
   *             When this field is not of type Type.XREF_SINGLE or
   *             Type.XREF_MULTIPLE
   */
  public Entity getXrefEntity() throws MolgenisModelException
  {
    Entity e = this.getEntity().getModel().getEntity(this.getXrefEntityName());
    if (e == null)
    {
      throw new MolgenisModelException("Xref entity '" + this.getXrefEntityName() + "' for entity '"
          + this.getEntity().getName() + "' not part of model.");
    }
    return e;
  }

  public String getXrefEntityName() throws MolgenisModelException
  {
    if (!(this.type instanceof XrefField) && !(this.type instanceof MrefField))
    {
      throw new MolgenisModelException("Field '" + this.getEntity().getName() + "." + this.getName()
          + "' is not a XREF, so xref-table cannot be retrieved.");
    }

    return this.xref_entity;

  }

  /**
   * Returns the name of the field of the entity this field is referencing to.
   * When this field is not of type Type.XREF_SINGLE or Type.XREF_MULTIPLE an
   * exception is raised.
   *
   * @return The name of the field of the entity this field is referencing.
   * @throws Exception
   * @throws Exception
   *             When this field is not of type Type.XREF_SINGLE or
   *             Type.XREF_MULTIPLE
   */
  public Field getXrefField() throws MolgenisModelException
  {
    if (!(this.type instanceof XrefField) && !(this.type instanceof MrefField))
    {
      throw new MolgenisModelException("Field is not a XREF, so xref-field cannot be retrieved.");
    }

    Field result = this.getXrefEntity().getAllField(this.getXrefFieldName());
    if (result == null)
    {
      throw new MolgenisModelException("xref_field is not known for field " + getEntity().getName() + "."
          + getName());
    }
    return result;
  }

  // FIXME consistency: throw MolgenisModelException if type is not correct
  public String getXrefFieldName()
  {
    return this.xref_field;
  }

  /**
   * Returns the label of this reference. When this field is not of type
   * Type.XREF_SINGLE or Type.XREF_MULTIPLE an exception is raised.
   *
   * @return The label of this reference.
   * @throws MolgenisModelException
   * @throws Exception
   *             When this field is not of type Type.XREF_SINGLE or
   *             Type.XREF_MULTIPLE
   */
  public List<String> getXrefLabelNames() throws MolgenisModelException
  {
    // label name = replace '.' and replace entity name if label entity ==
    // xref_entity
    List<String> label_names = new ArrayList<String>();
    for (String label : this.getXrefLabelsTemp())
    {
      label_names.add(label.replace(this.getXrefEntityName() + ".", ""));
    }
    return label_names;
  }

  /**
   * Return a tree wich describes the path to xref labels. This allows also to
   * use indirect secondary keys as labels. For example: Sample is identified
   * by {name,Investigation.name}. Investigation.name has a path via
   * sample.investigation.
   *
   * @return
   * @throws MolgenisModelException
   */
  public SimpleTree<SimpleTree<?>> getXrefLabelTree() throws MolgenisModelException
  {
    return getXrefLabelTree(true);
  }

  public SimpleTree<SimpleTree<?>> getXrefLabelTree(boolean useJavaNames) throws MolgenisModelException
  {
    List<String> labels = new ArrayList<String>();
    for (String label : this.getXrefLabelNames())
    {
      labels.add(getName() + "_" + GeneratorHelper.getJavaName(label, useJavaNames));
    }

    SimpleTree<SimpleTree<?>> root = new SimpleTree<SimpleTree<?>>(getName(), null);
    root.setValue(this);
    this.getXrefLabelTree(labels, root, useJavaNames);
    return root;
  }

  /**
   * Creates a tree with leafs that match labels and nodes that match
   * entities. xref fields will result in sub trees.
   *
   * @param labels
   *            to be matched
   * @param path
   *            so far in the tree to allow for recursion
   * @return tree of paths matching labels.
   * @throws MolgenisModelException
   */
  protected void getXrefLabelTree(List<String> labels, SimpleTree<?> parent) throws MolgenisModelException
  {
    getXrefLabelTree(labels, parent, true);
  }

  /**
   * Creates a tree with leafs that match labels and nodes that match
   * entities. xref fields will result in sub trees.
   *
   * @param labels
   *            to be matched
   * @param path
   *            so far in the tree to allow for recursion
   * @return tree of paths matching labels.
   * @throws MolgenisModelException
   */
  protected void getXrefLabelTree(List<String> labels, SimpleTree<?> parent, boolean useJavaNames)
      throws MolgenisModelException
  {
    for (Field f : this.getXrefEntity().getAllFields())
    {
      String name = parent.getName() + "_" + GeneratorHelper.getJavaName(f.getName(), useJavaNames);
      if (!(f.getType() instanceof XrefField) && !(f.getType() instanceof MrefField))
      {
        if (labels.contains(name))
        {
          Tree<SimpleTree<?>> leaf = new SimpleTree<SimpleTree<?>>(name, parent);
          leaf.setValue(f);
          // break;
        }
      }
    }

    for (Field f : this.getXrefEntity().getAllFields())
    {
      String name = parent.getName() + "_" + f.getName();

      if (f.getType() instanceof XrefField)
      {
        // check for cyclic relations
        // FIXME check for indirect cyclic relations or limit nesting
        // arbitrarily
        if (!f.getXrefEntity().equals(this.getXrefEntity()))
        {

          SimpleTree<SimpleTree<?>> node = new SimpleTree<SimpleTree<?>>(name, null);
          // get fields from subtree
          f.getXrefLabelTree(labels, node);
          // only attach the node if it leads to a label
          for (SimpleTree<?> child : node.getAllChildren())
          {
            if (labels.contains(child.getName()))
            {
              node.setParent(parent);
              node.setValue(f);
              break;
            }
          }
        }
      }
    }
  }

  public List<Field> getXrefLabelPath(String label) throws MolgenisModelException, DatabaseException
  {
    return this.allPossibleXrefLabels().get(label);
  }

  public List<Field> getXrefLabels() throws DatabaseException, MolgenisModelException
  {
    List<Field> result = new ArrayList<Field>();

    for (String label : getXrefLabelNames())
    {
      // absolute name
      if (label.contains("."))
      {
        result.add(this.getEntity().getModel().findField(label));
      } // path through xref to another field, path separated by _
        // caveat is fieldnames with '_' in the name
        // solution is to match against all possible xref_label
        // candidates
      else if (label.contains("_"))
      {
        // match agains all known labels
        Map<String, List<Field>> candidates = this.allPossibleXrefLabels();
        for (Entry<String, List<Field>> entry : candidates.entrySet())
        {
          String key = entry.getKey();
          if (key.toLowerCase().equals(label.toLowerCase()))
          {
            List<Field> value = entry.getValue();
            result.add(value.get(value.size() - 1));
          }
        }

        // e.g., Sample.experiment, is an xref itself, can be cascade of
        // xrefs actually
        // Field xrefField = new
        // Field(this.getEntity().getModel().findField(
        // this.getXrefEntity().getName() + "." + label.split("_")[0]));
        // xrefField.setXrefLabelNames(Arrays.asList(new String[]
        // { label.split("_")[1] }));

        // result.add(xrefField);

        // System.out.println(result.get(result.size()-1));
      } // local name
      else
      {
        Field target = this.getEntity().getModel().findField(this.getXrefEntity().getName() + "." + label);
        result.add(new Field(target));
      }
      // System.out.println(result);
    }
    return result;
  }

  // FIXME consistency: check if this is a xref field
  public List<String> getXrefLabelsTemp() throws MolgenisModelException
  {
    if (xref_labels == null || xref_labels.size() == 0)
    {
      if (this.getXrefEntity() == null)
      {
        throw new MolgenisModelException("Cannot find xref_entity='" + getXrefEntityName() + "' for "
            + getEntity().getName() + "." + getName());
      }
      if (this.getXrefEntity().getXrefLabels() != null)
      {
        return this.getXrefEntity().getXrefLabels();
      }
      else
      {
        return Arrays.asList(new String[]
        { this.xref_field });
      }
    }
    return xref_labels;
  }

  /**
   * Gets the name of the link-table when this field is a XREF_MULTIPLE. When
   * this field is not of type Type.XREF_MULTIPLE an exception is raised.
   *
   * @return The name of the linktable.
   * @throws Exception
   *             When this field is not of type Type.XREF_MULTIPLE
   */
  public String getMrefName()
  {
    // if (this.type != Type.XREF_MULTIPLE)
    // {
    // throw new Exception("Field is not a XREF with relation MULTIPLE, so
    // xref-linktable cannot be retrieved.");
    // }

    return this.mref_name;
  }

  /**
   * Sets the name of the link-table when this field is a XREF_MULTIPLE. When
   * this field is not of type Type.XREF_MULTIPLE an exception is raised.
   *
   * @param linktable
   *            The name of the linktable.
   * @throws Exception
   *             When this field is not of type Type.XREF_MULTIPLE
   */
  public void setMrefName(String linktable)
  {
    // if (this.type != Type.XREF_MULTIPLE)
    // {
    // throw new Exception("Field is not a XREF with relation MULTIPLE, so
    // xref-linktable cannot be set.");
    // }

    this.mref_name = linktable;
  }

  public String getMrefLocalid()
  {
    return mref_localid;
  }

  public void setMrefLocalid(String mref_localid)
  {
    this.mref_localid = mref_localid;
  }

  public String getMrefRemoteid()
  {
    return mref_remoteid;
  }

  public void setMrefRemoteid(String mref_remoteid)
  {
    this.mref_remoteid = mref_remoteid;
  }

  //
  /**
     *
     */
  public void setUserData(Object obj)
  {
    user_data = obj;
  }

  /**
     *
     */
  public Object getUserData()
  {
    return user_data;
  }

  public String getDefaultCode()
  {
    return default_code;
  }

  public void setDefaultCode(String default_code)
  {
    this.default_code = default_code;
  }

  // Object overloads
  /**
   * Returns a string representation of the Field.
   *
   * @return The string-representation.
   */
  @Override
  public String toString()
  {
    String str = "Field(";

    // entity
    str += "entity=" + entity.getName();

    // name/label
    str += ", name=" + name;

    // type
    str += ", type=" + type;
    if (type instanceof StringField || type instanceof CharField)
    {
      str += "[" + varchar_length + "]";
    }
    else if (type instanceof XrefField || type instanceof MrefField)
    {
      try
      {
        str += "[" + this.getXrefEntityName() + "." + this.getXrefFieldName() + "]";
      }
      catch (MolgenisModelException e)
      {
        e.printStackTrace();
      }
    }
    if (type instanceof MrefField)
    {
      str += ", mref_name=" + this.mref_name + ", mref_localid=" + this.mref_localid + ", mref_remoteid="
          + this.mref_remoteid;
    }
    if (type instanceof XrefField || type instanceof MrefField)
    {
      str += ", xref_label=" + new GeneratorHelper(null).toCsv(this.xref_labels);
    }

    // settings
    str += ", auto=" + auto;
    str += ", nillable=" + nillable;
    str += ", readonly=" + readonly;

    // default
    str += ", default=" + default_value;

    if (this.enum_options != null)
    {
      str += ", enum_options=" + this.enum_options;
    }

    // closure
    str += ")";

    return str;
  }

  /**
   * Indicates whether some other object is "equal to" this one.
   *
   * @param obj
   *            The reference object with which to compare.
   * @return True if this object is the same as the obj argument, false
   *         otherwise.
   */
  @Override
  public boolean equals(Object obj)
  {
    if (obj != null && obj instanceof Field)
    {
      return name.equals(((Field) obj).getName());
    }

    return false;
  }

  /**
   * Returns a hash code value for the Field. This hash-code is used for quick
   * searching in a vector of fields.
   *
   * @return The hash-value for this field.
   */
  @Override
  public int hashCode()
  {
    return this.name.hashCode();
  }

  // member variables
  /** */
  private Entity entity;
  /** The type of this field. */
  private FieldType type;
  /**
   * The name of this field, which needs to be unique for the associated
   * entity.
   */
  private String name;
  /** The label of this field, which is used for the user interface. */
  private String label;
  /** Whether this field is auto-assigned by the database. */
  private boolean auto;
  /** Whether this field can be NULL in the database. */
  private boolean nillable;
  /** Whether this field is read-only. */
  private boolean hidden;
  /** Whether this field is hidden. */
  private boolean readonly;
  /**
   * The string that should be set as the default value (is passed to the
   * database ...)
   */
  private String default_value = null;
  /** A short description of this field. */
  private String description;
  private String default_code;
  /** When this field a of type Type.ENUM, this vector contains the options */
  private Vector<String> enum_options;
  /**
   * When this field is of type Type.VARCHAR, this indicates the maximum
   * length of the string.
   */
  private int varchar_length;
  /**
   * When this field is of type Type.XREF_SINGLE or Type.XREF_MULTIPLE, this
   * is the name of the entity it is referencing.
   */
  private String xref_entity;
  /**
   * When this field is of type Type.XREF_SINGLE or Type.XREF_MULTIPLE, this
   * is the name of the field of the entity it is referencing.
   */
  private String xref_field;
  /**
   * When this field is of type Type.XREF_SINGLE or Type.XREF_MULTIPLE, this
   * is the label of the reference.
   */
  private List<String> xref_labels;
  /**
   * Boolean to indicate cascading delete
   */
  private boolean xref_cascade = false;
  /**
   * Boolean to indicate cascading delete
   */
  private String jpaCascade = null;
  /**
   * When this field is of type Type.XREF_MULTIPLE, this is the name of the
   * link-table.
   */
  private String mref_name;
  private String mref_localid;
  private String mref_remoteid;
  private boolean filter;
  private String filtertype;
  private String filterfield;
  private String filtervalue;
  /** */
  private boolean system;
  /** Contains a pointer to some user-data. */
  private Object user_data;
  /** Used to <annotation> */
  private String annotations;
  /** Used for serialization purposes. */
  private static final long serialVersionUID = -1879739243713730190L;
  private String tableName;

  public String getAnnotations()
  {
    return annotations;
  }

  public void setAnnotations(String annotations)
  {
    this.annotations = annotations;
  }

  public boolean hasFilter()
  {
    return filter;
  }

  public void setFilter(boolean filter)
  {
    this.filter = filter;
  }

  public String getFilterfield()
  {
    return filterfield;
  }

  public void setFilterfield(String filterfield)
  {
    this.filterfield = filterfield;
  }

  public String getFiltertype()
  {
    return filtertype;
  }

  public void setFiltertype(String filtertype)
  {
    this.filtertype = filtertype;
  }

  public String getFiltervalue()
  {
    return filtervalue;
  }

  public void setNillable(boolean nillable)
  {
    this.nillable = nillable;
  }

  public void setFiltervalue(String filtervalue)
  {
    this.filtervalue = filtervalue;
  }

  public void setEntity(Entity entity)
  {
    this.entity = entity;
  }

  // FIXME rename to setXrefFieldName
  public void setXrefField(String xrefField)
  {
    this.xref_field = xrefField;

  }

  public void setXrefLabelNames(List<String> labelNames)
  {
    this.xref_labels = labelNames;

  }

  public Map<String, List<Field>> allPossibleXrefLabels() throws MolgenisModelException, DatabaseException
  {
    if (!(this.getType() instanceof XrefField) && !(this.getType() instanceof MrefField))
    {
      throw new MolgenisModelException("asking xref labels for non-xref field");
    }

    Map<String, List<Field>> result = new LinkedHashMap<String, List<Field>>();
    for (Unique key : getXrefEntity().getAllKeys()) // get all except
                            // primary key
    // if (!key.equals(getXrefEntity().getAllKeys().firstElement()))
    // {
    {
      for (Field f : key.getFields())
      {
        if (f.getType() instanceof XrefField || f.getType() instanceof MrefField)
        {
          f = getXrefEntity().getAllField(f.getName());

          Map<String, List<Field>> subpaths = f.allPossibleXrefLabels();
          for (Entry<String, List<Field>> pair : subpaths.entrySet())
          {
            List<Field> path = pair.getValue();
            path.add(0, f);
            String label = f.getName() + "_" + pair.getKey();
            result.put(label, path);

            // if
            // (!f.getEntity().getName().equals(getXrefEntity().getName()))
            // {
            //
            // System.out.println("PATH FOR " +
            // this.getEntity().getName() + "." + this.getName()
            // + "=" + this.getName() + "_" + label + " " + "field="
            // + f.getEntity().getName()
            // + " " + getXrefEntity().getName());
            // System.out.print(this.getEntity().getName() + "." +
            // this.getName());
            // for (Field pathField : path)
            // {
            // System.out
            // .print("->" + pathField.getEntity().getName() + "." +
            // pathField.getName());
            // }
            // System.out.println();
            // }
            //
            // else
            // {
            result.put(label, path);
            // }

          }
        }
        else
        {
          List<Field> path = new ArrayList<Field>();
          path.add(f);
          result.put(f.getName(), path);
        }
        // }
      }
    }

    return result;
  }

  /**
   * Helper method to find labels within the same entity that point to the
   * same endpoint. E.g. suppose fields protocol_investigation_name maps to
   * same entity as investigatio_name
   *
   * @param xrefField
   * @return
   * @throws MolgenisModelException
   * @throws DatabaseException
   */
  // public List<String> labelsToSameEndpoint(String xref_label) throws
  // MolgenisModelException, DatabaseException
  // {
  // List<String> result = new ArrayList<String>();
  //
  // // get the endpoint, if any
  // List<Field> pathToEndpoint =
  // this.allPossibleXrefLabels().get(xref_label);
  // if (pathToEndpoint == null)
  // {
  // String knownLabels = "";
  // for (String label : this.allPossibleXrefLabels().keySet())
  // knownLabels += ", "+label;
  // throw new MolgenisModelException("xref_label '" + xref_label +
  // "'unknown for field "
  // + this.getEntity().getName() + "." + this.getName() +
  // ". Known labels are " + knownLabels);
  // }
  // else
  // {
  // Field endpoint = pathToEndpoint.get(pathToEndpoint.size() - 1);
  //
  // for (Field otherField : getEntity().getAllFields())
  // {
  // // check the the other xref fields
  // if (otherField.getType() instanceof XrefField && otherField != this)
  // {
  // // check all the labels of this other field
  // Map<String, List<Field>> all_xref_labels =
  // otherField.allPossibleXrefLabels();
  // for (String other_label : all_xref_labels.keySet())
  // {
  // // check endpoint
  // List<Field> pathToOtherEndpoint = all_xref_labels.get(other_label);
  // Field otherEndPoint = pathToOtherEndpoint.get(pathToOtherEndpoint.size()
  // - 1);
  //
  // if (endpoint.getName().equals(otherEndPoint.getName())
  // &&
  // endpoint.getEntity().getName().equals(otherEndPoint.getEntity().getName()))
  // {
  // logger.debug("FOUND " + otherEndPoint.getEntity().getName() + "."
  // + otherEndPoint.getName() + " EQUALS " + endpoint.getEntity().getName() +
  // "."
  // + endpoint.getName());
  // result.add(otherField.getName().toLowerCase() + "_" + other_label);
  // }
  // }
  // }
  // }
  // }
  //
  // return result;
  // }
  public Integer getLength() throws MolgenisModelException
  {
    if (this.getType() instanceof StringField)
    {
      return this.getVarCharLength();
    }
    return null;
  }

  public synchronized boolean isXrefCascade()
  {
    return xref_cascade;
  }

  public synchronized void setXrefCascade(boolean xrefCascade)
  {
    xref_cascade = xrefCascade;
  }

  public String getJpaCascade()
  {
    return jpaCascade;
  }

  public void setJpaCascade(String jpaCascade)
  {
    this.jpaCascade = jpaCascade;
  }

  public void setTableName(String tableName)
  {
    this.tableName = tableName;
  }

  public String getTableName()
  {
    return this.tableName;
  }

  // FIXME database specific: delete method or move to utility class
  public String getSqlName()
  {
    if (StringUtils.isNotEmpty(this.tableName))
    {
      return WordUtils.capitalize(this.tableName) + "." + this.name;
    }
    else
    {
      return this.name;
    }
  }
}
TOP

Related Classes of org.molgenis.model.elements.Field

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.