/**
  * Constructs a DetailEntityItem using the fieldName and suffixId
  *
  * @param fieldName the fieldName that represents the relationship
  * @param suffixId used to generate field id
  */
 public DetailEntityItem(
     JpaEntityMetadata childEntityMetadata,
     ControllerMetadata controllerMetadata,
     String detailSuffix,
     EntityItem rootEntity) {
   super(
       childEntityMetadata.getDestination().getSimpleTypeName(),
       detailSuffix,
       childEntityMetadata.isReadOnly());
   this.level = controllerMetadata.getDetailsFieldInfo().size();
   this.rootEntity = rootEntity;
   this.fieldInfo = controllerMetadata.getLastDetailsInfo();
   this.fieldName = fieldInfo.fieldName;
   this.fieldNameCapitalized = StringUtils.capitalize(fieldName);
   this.tabLinkCode = null;
   this.pathString = controllerMetadata.getDetailsPathAsString("-");
   this.pathStringFieldNames = controllerMetadata.getDetailsPathAsString(".");
   this.z = calculateZ();
   buildDetailItemId(detailSuffix);
 }
  @Override
  public void installLanguage(final I18n language, final boolean useAsDefault, final Pom module) {

    // Check if provided module match with application modules features
    Validate.isTrue(
        getTypeLocationService().hasModuleFeature(module, ModuleFeatureName.APPLICATION),
        "ERROR: Provided module doesn't match with application modules features. "
            + "Execute this operation again and provide a valid application module.");

    Validate.notNull(language, "ERROR: You should provide a valid language code.");

    if (language.getLocale() == null) {
      LOGGER.warning("ERROR: Provided language is not valid.");
      return;
    }

    final LogicalPath resourcesPath =
        LogicalPath.getInstance(Path.SRC_MAIN_RESOURCES, module.getModuleName());

    final String targetDirectory = getPathResolver().getIdentifier(resourcesPath, "");

    // Getting message.properties file
    String messageBundle = "";

    if (language.getLocale().equals(Locale.ENGLISH)) {
      messageBundle = targetDirectory + "messages.properties";
    } else {
      messageBundle =
          targetDirectory
              .concat("messages_")
              .concat(language.getLocale().getLanguage().concat(".properties"));
    }

    if (!getFileManager().exists(messageBundle)) {
      InputStream inputStream = null;
      OutputStream outputStream = null;
      try {
        inputStream = language.getMessageBundle();
        outputStream = getFileManager().createFile(messageBundle).getOutputStream();
        IOUtils.copy(inputStream, outputStream);
      } catch (final Exception e) {
        throw new IllegalStateException(
            "Encountered an error during copying of message bundle MVC JSP addon.", e);
      } finally {
        IOUtils.closeQuietly(inputStream);
        IOUtils.closeQuietly(outputStream);
      }
    }

    // Install flag
    final String flagGraphic =
        targetDirectory
            .concat("static/public/img/")
            .concat(language.getLocale().getLanguage())
            .concat(".png");
    if (!getFileManager().exists(flagGraphic)) {
      InputStream inputStream = null;
      OutputStream outputStream = null;
      try {
        inputStream = language.getFlagGraphic();
        outputStream = getFileManager().createFile(flagGraphic).getOutputStream();
        IOUtils.copy(inputStream, outputStream);
      } catch (final Exception e) {
        throw new IllegalStateException(
            "Encountered an error during copying of flag graphic for MVC JSP addon.", e);
      } finally {
        IOUtils.closeQuietly(inputStream);
        IOUtils.closeQuietly(outputStream);
      }
    }

    // Update @WebMvcConfiguration annotation defining defaultLanguage
    // attribute
    if (useAsDefault) {

      // Obtain all existing configuration classes annotated with
      // @RooWebMvcConfiguration
      Set<ClassOrInterfaceTypeDetails> configurationClasses =
          getTypeLocationService()
              .findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_WEB_MVC_CONFIGURATION);

      for (ClassOrInterfaceTypeDetails configurationClass : configurationClasses) {
        // If configuration class is located in the provided module
        if (configurationClass.getType().getModule().equals(module.getModuleName())) {
          ClassOrInterfaceTypeDetailsBuilder cidBuilder =
              new ClassOrInterfaceTypeDetailsBuilder(configurationClass);
          AnnotationMetadataBuilder annotation =
              cidBuilder.getDeclaredTypeAnnotation(RooJavaType.ROO_WEB_MVC_CONFIGURATION);
          annotation.addStringAttribute("defaultLanguage", language.getLocale().getLanguage());

          // Update configuration class
          getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build());
        }
      }

      LOGGER.log(
          Level.INFO,
          String.format(
              "INFO: Default language of your project has been changed to %s.",
              language.getLanguage()));
    }

    // Get all controllers and update its message bundles
    Set<ClassOrInterfaceTypeDetails> controllers =
        getTypeLocationService()
            .findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_CONTROLLER);
    for (ClassOrInterfaceTypeDetails controller : controllers) {
      getMetadataService().evictAndGet(ControllerMetadata.createIdentifier(controller));
    }

    // Add application property
    getApplicationConfigService()
        .addProperty(
            module.getModuleName(), "spring.messages.fallback-to-system-locale", "false", "", true);
  }