/**
  * Convenience method to get the fully qualified class name of a field on a type in a project
  *
  * @param oracle The DMO representing a project
  * @param fullyQualifiedClassName The FQCN of the type
  * @param fieldName The field Name
  * @return
  */
 public static String getFieldClassName(
     final ProjectDataModelOracle oracle,
     final String fullyQualifiedClassName,
     final String fieldName) {
   final ModelField field = getField(oracle, fullyQualifiedClassName, fieldName);
   return field == null ? null : field.getClassName();
 }
 private static ModelField getField(
     final ProjectDataModelOracle oracle,
     final String fullyQualifiedClassName,
     final String fieldName) {
   final String shortName = getFactNameFromType(oracle, fullyQualifiedClassName);
   final ModelField[] fields = oracle.getProjectModelFields().get(shortName);
   if (fields == null) {
     return null;
   }
   for (ModelField modelField : fields) {
     if (modelField.getName().equals(fieldName)) {
       return modelField;
     }
   }
   return null;
 }
  private ModelField getField(final String modelClassName, final String fieldName) {
    final String fgcnByFactName = getFQCNByFactName(modelClassName);
    final ModelField[] fields = projectModelFields.get(fgcnByFactName);

    if (fields == null) {
      return null;
    }

    for (ModelField modelField : fields) {
      if (modelField.getName().equals(fieldName)) {
        return AsyncPackageDataModelOracleUtilities.correctModelFields(
            packageName, imports, modelField);
      }
    }

    return null;
  }
 private static String getFactNameFromType(
     final ProjectDataModelOracle oracle, final String fullyQualifiedClassName) {
   if (fullyQualifiedClassName == null) {
     return null;
   }
   if (oracle.getProjectModelFields().containsKey(fullyQualifiedClassName)) {
     return fullyQualifiedClassName;
   }
   for (Map.Entry<String, ModelField[]> entry : oracle.getProjectModelFields().entrySet()) {
     for (ModelField mf : entry.getValue()) {
       if (DataType.TYPE_THIS.equals(mf.getName())
           && fullyQualifiedClassName.equals(mf.getClassName())) {
         return entry.getKey();
       }
     }
   }
   return null;
 }
  @Override
  public String getFieldClassName(final String modelClassName, final String fieldName) {
    // Check fields
    final ModelField field = getField(modelClassName, fieldName);
    if (field != null) {
      return field.getClassName();
    }

    // Check method information
    final String fgcnModelClassName = getFQCNByFactName(modelClassName);
    final List<MethodInfo> mis = projectMethodInformation.get(fgcnModelClassName);
    if (mis != null) {
      for (MethodInfo mi : mis) {
        if (mi.getName().equals(fieldName)) {
          return mi.getReturnClassType();
        }
      }
    }

    return null;
  }
  /**
   * Returns fact's name from type
   *
   * @param type for example org.test.Person or Person
   * @return Shorter type name Person, not org.test.Person
   */
  @Override
  public String getFactNameFromType(final String type) {
    if (type == null || type.isEmpty()) {
      return null;
    }
    if (filteredModelFields.containsKey(type)) {
      return type;
    }
    for (Map.Entry<String, ModelField[]> entry : filteredModelFields.entrySet()) {
      for (ModelField mf : entry.getValue()) {
        if (DataType.TYPE_THIS.equals(mf.getName()) && type.equals(mf.getClassName())) {
          return entry.getKey();
        }
      }
    }

    final String fgcnByFactName = getFQCNByFactName(type);
    if (projectModelFields.containsKey(fgcnByFactName)) {
      return AsyncPackageDataModelOracleUtilities.getTypeName(fgcnByFactName);
    }

    return null;
  }
 // AsyncPackageDataModelOracle.getFactNameFromType() uses THIS to determine the simple Type from a
 // FQCN.
 // Therefore ensure we provide this minimal information for every Type in the DMO to prevent
 // getFactNameFromType()
 // needing a callback to the server which makes things more complicated than really needed.
 private static ModelField[] makeLazyProxyModelField(final ModelField[] modelFields) {
   for (ModelField modelField : modelFields) {
     if (DataType.TYPE_THIS.equals(modelField.getName())) {
       final ModelField[] result = new ModelField[1];
       // LazyModelField is a place-holder to tell AsyncPackageDataModelOracle that it needs to
       // load more information
       result[0] =
           new LazyModelField(
               modelField.getName(),
               modelField.getClassName(),
               modelField.getClassType(),
               modelField.getOrigin(),
               modelField.getAccessorsAndMutators(),
               modelField.getType());
       return result;
     }
   }
   return null;
 }