public static DatasetField createNewEmptyDatasetField(DatasetFieldType dsfType, Object dsv) {

    DatasetField dsfv = createNewEmptyDatasetField(dsfType);
    // TODO - a better way to handle this?
    if (dsv.getClass().getName().equals("edu.harvard.iq.dataverse.DatasetVersion")) {
      dsfv.setDatasetVersion((DatasetVersion) dsv);
    } else {
      dsfv.setTemplate((Template) dsv);
    }

    return dsfv;
  }
 public String getCompoundDisplayValue() {
   String returnString = "";
   for (DatasetFieldCompoundValue dscv : datasetFieldCompoundValues) {
     for (DatasetField dsf : dscv.getChildDatasetFields()) {
       for (String value : dsf.getValues()) {
         if (!(value == null)) {
           returnString += (returnString.equals("") ? "" : "; ") + value.trim();
         }
       }
     }
   }
   return returnString;
 }
 /**
  * Groups a list of fields by the block they belong to.
  *
  * @param fields well, duh.
  * @return a map, mapping each block to the fields that belong to it.
  */
 public static Map<MetadataBlock, List<DatasetField>> groupByBlock(List<DatasetField> fields) {
   Map<MetadataBlock, List<DatasetField>> retVal = new HashMap<>();
   for (DatasetField f : fields) {
     MetadataBlock metadataBlock = f.getDatasetFieldType().getMetadataBlock();
     List<DatasetField> lst = retVal.get(metadataBlock);
     if (lst == null) {
       retVal.put(metadataBlock, new LinkedList<>(Collections.singleton(f)));
     } else {
       lst.add(f);
     }
   }
   return retVal;
 }
  private DatasetField copy(Object version, DatasetFieldCompoundValue parent) {
    DatasetField dsf = new DatasetField();
    dsf.setDatasetFieldType(datasetFieldType);

    if (version != null) {
      if (version.getClass().getName().equals("edu.harvard.iq.dataverse.DatasetVersion")) {
        dsf.setDatasetVersion((DatasetVersion) version);
      } else {
        dsf.setTemplate((Template) version);
      }
    }

    dsf.setParentDatasetFieldCompoundValue(parent);
    dsf.setControlledVocabularyValues(controlledVocabularyValues);

    for (DatasetFieldValue dsfv : datasetFieldValues) {
      dsf.getDatasetFieldValues().add(dsfv.copy(dsf));
    }

    for (DatasetFieldCompoundValue compoundValue : datasetFieldCompoundValues) {
      dsf.getDatasetFieldCompoundValues().add(compoundValue.copy(dsf));
    }

    return dsf;
  }
  private static DatasetField createNewEmptyDatasetField(DatasetFieldType dsfType) {
    DatasetField dsfv = new DatasetField();
    dsfv.setDatasetFieldType(dsfType);

    if (dsfType.isPrimitive()) {
      if (!dsfType.isControlledVocabulary()) {
        dsfv.getDatasetFieldValues().add(new DatasetFieldValue(dsfv));
      }
    } else { // compound field
      dsfv.getDatasetFieldCompoundValues()
          .add(DatasetFieldCompoundValue.createNewEmptyDatasetFieldCompoundValue(dsfv));
    }

    return dsfv;
  }
  public void setValueDisplayOrder() {
    if (this.getDatasetFieldType().isPrimitive()
        && !this.getDatasetFieldType().isControlledVocabulary()) {
      for (int i = 0; i < datasetFieldValues.size(); i++) {
        datasetFieldValues.get(i).setDisplayOrder(i);
      }

    } else if (this.getDatasetFieldType().isCompound()) {
      for (int i = 0; i < datasetFieldCompoundValues.size(); i++) {
        DatasetFieldCompoundValue compoundValue = datasetFieldCompoundValues.get(i);
        compoundValue.setDisplayOrder(i);
        for (DatasetField dsf : compoundValue.getChildDatasetFields()) {
          dsf.setValueDisplayOrder();
        }
      }
    }
  }
  private boolean isEmpty(boolean forDisplay) {
    if (datasetFieldType.isPrimitive()) { // primitive
      for (String value : getValues()) {
        if (!StringUtils.isBlank(value) && !(forDisplay && DatasetField.NA_VALUE.equals(value))) {
          return false;
        }
      }
    } else { // compound
      for (DatasetFieldCompoundValue cv : datasetFieldCompoundValues) {
        for (DatasetField subField : cv.getChildDatasetFields()) {
          if (!subField.isEmpty(forDisplay)) {
            return false;
          }
        }
      }
    }

    return true;
  }
 // originally this was an overloaded method, but we renamed it to get around an issue with Bean
 // Validation
 // (that looked t overloaded methods, when it meant to look at overriden methods
 public static DatasetField createNewEmptyChildDatasetField(
     DatasetFieldType dsfType, DatasetFieldCompoundValue compoundValue) {
   DatasetField dsfv = createNewEmptyDatasetField(dsfType);
   dsfv.setParentDatasetFieldCompoundValue(compoundValue);
   return dsfv;
 }
 @Override
 public int compare(DatasetField o1, DatasetField o2) {
   return Integer.compare(
       o1.getDatasetFieldType().getDisplayOrder(),
       o2.getDatasetFieldType().getDisplayOrder());
 }