@Test
  public void testEnumAddElement() throws Exception {

    // Set up
    final File file = getResource(ENUM_FILE_PATH);
    final String fileContents = getResourceContents(file);
    final String filePath = file.getCanonicalPath();

    final ClassOrInterfaceTypeDetails enumDetails =
        typeParsingService.getTypeFromString(fileContents, ENUM_DECLARED_BY_MID, ENUM_TYPE);

    // Invoke
    final String result =
        typeParsingService.updateAndGetCompilationUnitContents(filePath, enumDetails);

    saveResult(file, result);

    final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(enumDetails);

    cidBuilder.addEnumConstant(new JavaSymbolName("ALIEN"));

    final ClassOrInterfaceTypeDetails enumDetails2 = cidBuilder.build();

    // Invoke
    final String result2 =
        typeParsingService.updateAndGetCompilationUnitContents(filePath, enumDetails2);

    saveResult(file, result2, "addedConst");

    checkEnum(result2);

    assertTrue(result2.contains("MALE, FEMALE, ALIEN"));
  }
  @Override
  public void restResource(
      final JavaType type, final boolean hide, final String path, final String rel) {

    final ClassOrInterfaceTypeDetails typeDetails = typeLocationService.getTypeDetails(type);
    Validate.notNull(typeDetails, "The repository specified, '" + type + "'doesn't exist");

    final AnnotationMetadataBuilder annotationBuilder =
        new AnnotationMetadataBuilder(REST_RESOURCE);
    if (hide) {
      annotationBuilder.addBooleanAttribute("exported", false);
    }
    if (!StringUtils.isEmpty(path)) {
      annotationBuilder.addStringAttribute("path", path);
    }
    if (!StringUtils.isEmpty(rel)) {
      annotationBuilder.addStringAttribute("rel", rel);
    }

    final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(typeDetails);

    if (MemberFindingUtils.getAnnotationOfType(typeDetails.getAnnotations(), REST_RESOURCE)
        != null) {
      cidBuilder.removeAnnotation(REST_RESOURCE);
    }

    cidBuilder.addAnnotation(annotationBuilder);

    typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
  }
 public static ClassOrInterfaceTypeDetails addField(
     final ClassOrInterfaceTypeDetails ptd, final FieldMetadata field) {
   final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
       new ClassOrInterfaceTypeDetailsBuilder(ptd);
   cidBuilder.addField(field);
   return cidBuilder.build();
 }
  public void addEnumConstant(
      final String physicalTypeIdentifier, final JavaSymbolName constantName) {
    Assert.hasText(physicalTypeIdentifier, "Type identifier not provided");
    Assert.notNull(constantName, "Constant name required");

    // Obtain the physical type and itd mutable details
    PhysicalTypeMetadata ptm = (PhysicalTypeMetadata) metadataService.get(physicalTypeIdentifier);
    Assert.notNull(
        ptm,
        "Java source code unavailable for type "
            + PhysicalTypeIdentifier.getFriendlyName(physicalTypeIdentifier));
    PhysicalTypeDetails ptd = ptm.getMemberHoldingTypeDetails();
    Assert.notNull(
        ptd,
        "Java source code details unavailable for type "
            + PhysicalTypeIdentifier.getFriendlyName(physicalTypeIdentifier));
    ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder((ClassOrInterfaceTypeDetails) ptd);

    // Ensure it's an enum
    Assert.isTrue(
        cidBuilder.getPhysicalTypeCategory() == PhysicalTypeCategory.ENUMERATION,
        PhysicalTypeIdentifier.getFriendlyName(physicalTypeIdentifier) + " is not an enum");

    cidBuilder.addEnumConstant(constantName);
    createOrUpdateTypeOnDisk(cidBuilder.build());
  }
Example #5
0
  public void injectEmailTemplate(
      final JavaType targetType, final JavaSymbolName fieldName, final boolean async) {
    Assert.notNull(targetType, "Java type required");
    Assert.notNull(fieldName, "Field name required");

    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    annotations.add(new AnnotationMetadataBuilder(AUTOWIRED));

    // Obtain the physical type and its mutable class details
    final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(targetType);
    ClassOrInterfaceTypeDetails existing = typeLocationService.findClassOrInterface(targetType);
    if (existing == null) {
      log.warning(
          "Aborting: Unable to find metadata for target type '"
              + targetType.getFullyQualifiedTypeName()
              + "'");
      return;
    }
    final ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(existing);

    // Add the MailSender field
    final FieldMetadataBuilder mailSenderFieldBuilder =
        new FieldMetadataBuilder(
            declaredByMetadataId, PRIVATE_TRANSIENT, annotations, fieldName, MAIL_SENDER);
    classOrInterfaceTypeDetailsBuilder.addField(mailSenderFieldBuilder.build());

    // Add the "sendMessage" method
    classOrInterfaceTypeDetailsBuilder.addMethod(
        getSendMethod(fieldName, async, declaredByMetadataId, classOrInterfaceTypeDetailsBuilder));
    typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build());
  }
 public static ClassOrInterfaceTypeDetails addAnnotation(
     final ClassOrInterfaceTypeDetails ptd, final AnnotationMetadata annotation) {
   final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
       new ClassOrInterfaceTypeDetailsBuilder(ptd);
   cidBuilder.addAnnotation(annotation);
   return cidBuilder.build();
 }
  private void createIdentifierClass(final JavaType identifierType) {
    final List<AnnotationMetadataBuilder> identifierAnnotations =
        new ArrayList<AnnotationMetadataBuilder>();

    final AnnotationMetadataBuilder identifierBuilder =
        new AnnotationMetadataBuilder(ROO_IDENTIFIER);
    identifierBuilder.addBooleanAttribute(DB_MANAGED.getSymbolName(), true);
    identifierAnnotations.add(identifierBuilder);

    // Produce identifier itself
    final String declaredByMetadataId =
        PhysicalTypeIdentifier.createIdentifier(
            identifierType, projectOperations.getPathResolver().getFocusedPath(Path.SRC_MAIN_JAVA));
    final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(
            declaredByMetadataId,
            Modifier.PUBLIC | Modifier.FINAL,
            identifierType,
            PhysicalTypeCategory.CLASS);
    cidBuilder.setAnnotations(identifierAnnotations);
    typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());

    shell.flash(
        Level.FINE,
        "Created " + identifierType.getFullyQualifiedTypeName(),
        DbreDatabaseListenerImpl.class.getName());
    shell.flash(Level.FINE, "", DbreDatabaseListenerImpl.class.getName());
  }
  /**
   * Creates a new DBRE-managed entity from the given table
   *
   * @param javaType the name of the entity to be created (required)
   * @param table the table from which to create the entity (required)
   * @param activeRecord whether to create "active record" CRUD methods in the new entity
   * @return the newly created entity
   */
  private ClassOrInterfaceTypeDetails createNewManagedEntityFromTable(
      final JavaType javaType, final Table table, final boolean activeRecord) {
    // Create type annotations for new entity
    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    annotations.add(new AnnotationMetadataBuilder(ROO_JAVA_BEAN));
    annotations.add(new AnnotationMetadataBuilder(ROO_TO_STRING));

    // Find primary key from db metadata and add identifier attributes to
    // @RooJpaEntity
    final AnnotationMetadataBuilder jpaAnnotationBuilder =
        new AnnotationMetadataBuilder(activeRecord ? ROO_JPA_ACTIVE_RECORD : ROO_JPA_ENTITY);
    manageIdentifier(javaType, jpaAnnotationBuilder, new HashSet<JavaSymbolName>(), table);

    if (!hasVersionField(table)) {
      jpaAnnotationBuilder.addStringAttribute(VERSION_FIELD, "");
    }
    if (table.isDisableGeneratedIdentifiers()) {
      jpaAnnotationBuilder.addStringAttribute(SEQUENCE_NAME_FIELD, "");
    }

    jpaAnnotationBuilder.addStringAttribute("table", table.getName());
    if (!DbreModelService.NO_SCHEMA_REQUIRED.equals(table.getSchema().getName())) {
      jpaAnnotationBuilder.addStringAttribute("schema", table.getSchema().getName());
    }

    annotations.add(jpaAnnotationBuilder);

    // Add @RooDbManaged
    annotations.add(getRooDbManagedAnnotation());

    final JavaType superclass = OBJECT;
    final List<JavaType> extendsTypes = new ArrayList<JavaType>();
    extendsTypes.add(superclass);

    // Create entity class
    final String declaredByMetadataId =
        PhysicalTypeIdentifier.createIdentifier(
            javaType, projectOperations.getPathResolver().getFocusedPath(Path.SRC_MAIN_JAVA));
    final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(
            declaredByMetadataId, Modifier.PUBLIC, javaType, PhysicalTypeCategory.CLASS);
    cidBuilder.setExtendsTypes(extendsTypes);
    cidBuilder.setAnnotations(annotations);

    final ClassOrInterfaceTypeDetails entity = cidBuilder.build();
    typeManagementService.createOrUpdateTypeOnDisk(entity);

    shell.flash(
        Level.FINE,
        "Created " + javaType.getFullyQualifiedTypeName(),
        DbreDatabaseListenerImpl.class.getName());
    shell.flash(Level.FINE, "", DbreDatabaseListenerImpl.class.getName());

    return entity;
  }
  public void addField(final FieldMetadata field) {
    Assert.notNull(field, "Field metadata not provided");

    // Obtain the physical type and ITD mutable details
    PhysicalTypeMetadata ptm =
        (PhysicalTypeMetadata) metadataService.get(field.getDeclaredByMetadataId());
    Assert.notNull(
        ptm,
        "Java source code unavailable for type "
            + PhysicalTypeIdentifier.getFriendlyName(field.getDeclaredByMetadataId()));
    PhysicalTypeDetails ptd = ptm.getMemberHoldingTypeDetails();
    Assert.notNull(
        ptd,
        "Java source code details unavailable for type "
            + PhysicalTypeIdentifier.getFriendlyName(field.getDeclaredByMetadataId()));
    ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder((ClassOrInterfaceTypeDetails) ptd);

    // Automatically add JSR 303 (Bean Validation API) support if there is
    // no current JSR 303 support but a JSR 303 annotation is present
    boolean jsr303Required = false;
    for (AnnotationMetadata annotation : field.getAnnotations()) {
      if (annotation
          .getAnnotationType()
          .getFullyQualifiedTypeName()
          .startsWith("javax.validation")) {
        jsr303Required = true;
        break;
      }
    }

    LogicalPath path = PhysicalTypeIdentifier.getPath(cidBuilder.getDeclaredByMetadataId());

    if (jsr303Required) {
      // It's more likely the version below represents a later version
      // than any specified in the user's own dependency list
      projectOperations.addDependency(
          path.getModule(), "javax.validation", "validation-api", "1.0.0.GA");
    }
    cidBuilder.addField(field);
    createOrUpdateTypeOnDisk(cidBuilder.build());
  }
  /** {@inheritDoc} */
  public void annotateType(final JavaType type, final JavaPackage javaPackage) {
    // TODO check for existing controller

    // Use Roo's Assert type for null checks
    Validate.notNull(type, "Java type required");
    Validate.notNull(javaPackage, "Java package required, web mvc all command package required");

    // Obtain ClassOrInterfaceTypeDetails for this java type
    ClassOrInterfaceTypeDetails entityDetails = typeLocationService.getTypeDetails(type);

    // Test if the annotation already exists on the target type
    if (entityDetails != null
        && MemberFindingUtils.getAnnotationOfType(
                entityDetails.getAnnotations(), new JavaType(RooEnvers.class.getName()))
            == null) {
      ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder =
          new ClassOrInterfaceTypeDetailsBuilder(entityDetails);

      // Create JavaType instance for the add-ons trigger annotation
      JavaType rooEnvers = new JavaType(RooEnvers.class.getName());

      // Create Annotation metadata
      AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(rooEnvers);

      // Add annotation to target type
      classOrInterfaceTypeDetailsBuilder.addAnnotation(annotationBuilder.build());

      // Save changes to disk
      typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build());
    }

    // Get details for existing controller
    JavaType typeController =
        new JavaType(
            javaPackage.getFullyQualifiedPackageName()
                + "."
                + type.getSimpleTypeName()
                + "Controller");
    ClassOrInterfaceTypeDetails typeControllerDetails =
        typeLocationService.getTypeDetails(typeController);

    // Add annotation @RooEnversController to existing controller
    ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(typeControllerDetails);
    JavaType rooEnversController =
        new JavaType("de.eightbitboy.roo.envers.controller.RooEnversController");

    final List<AnnotationAttributeValue<?>> rooEnversControllerAttributes =
        new ArrayList<AnnotationAttributeValue<?>>();
    rooEnversControllerAttributes.add(new ClassAttributeValue(new JavaSymbolName("type"), type));

    AnnotationMetadataBuilder annotationBuilder =
        new AnnotationMetadataBuilder(rooEnversController, rooEnversControllerAttributes);
    classOrInterfaceTypeDetailsBuilder.addAnnotation(annotationBuilder.build());

    typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build());
  }
 private MethodMetadataBuilder getFindMethod(
     ClassOrInterfaceTypeDetailsBuilder locatorBuilder,
     String declaredById,
     JavaType targetType,
     JavaType idType) {
   MemberTypeAdditions findMethodAdditions =
       layerService.getMemberTypeAdditions(
           declaredById,
           PersistenceCustomDataKeys.FIND_METHOD.name(),
           targetType,
           idType,
           LAYER_POSITION,
           new MethodParameter(idType, "id"));
   InvocableMemberBodyBuilder invocableMemberBodyBuilder =
       InvocableMemberBodyBuilder.getInstance();
   invocableMemberBodyBuilder
       .append("return ")
       .append(findMethodAdditions.getMethodCall())
       .append(";");
   findMethodAdditions.copyAdditionsTo(locatorBuilder, locatorBuilder.build());
   MethodMetadataBuilder findMethodBuilder =
       new MethodMetadataBuilder(
           declaredById,
           Modifier.PUBLIC,
           new JavaSymbolName("find"),
           targetType,
           invocableMemberBodyBuilder);
   JavaType wildEntityType =
       new JavaType(
           targetType.getFullyQualifiedTypeName(),
           0,
           DataType.VARIABLE,
           JavaType.WILDCARD_EXTENDS,
           null);
   JavaType classParameterType =
       new JavaType(
           JavaType.CLASS.getFullyQualifiedTypeName(),
           0,
           DataType.TYPE,
           null,
           Arrays.asList(wildEntityType));
   findMethodBuilder.addParameter("clazz", classParameterType);
   findMethodBuilder.addParameter("id", idType);
   return findMethodBuilder;
 }
  public void setupService(
      final JavaType interfaceType, final JavaType classType, final JavaType domainType) {
    Assert.notNull(interfaceType, "Interface type required");
    Assert.notNull(classType, "Class type required");
    Assert.notNull(domainType, "Domain type required");

    String interfaceIdentifier =
        pathResolver.getFocusedCanonicalPath(Path.SRC_MAIN_JAVA, interfaceType);
    String classIdentifier = pathResolver.getFocusedCanonicalPath(Path.SRC_MAIN_JAVA, classType);

    if (fileManager.exists(interfaceIdentifier) || fileManager.exists(classIdentifier)) {
      return; // Type exists already - nothing to do
    }

    // First build interface type
    AnnotationMetadataBuilder interfaceAnnotationMetadata =
        new AnnotationMetadataBuilder(ROO_SERVICE);
    interfaceAnnotationMetadata.addAttribute(
        new ArrayAttributeValue<ClassAttributeValue>(
            new JavaSymbolName("domainTypes"),
            Arrays.asList(new ClassAttributeValue(new JavaSymbolName("foo"), domainType))));
    String interfaceMdId =
        PhysicalTypeIdentifier.createIdentifier(
            interfaceType, pathResolver.getPath(interfaceIdentifier));
    ClassOrInterfaceTypeDetailsBuilder interfaceTypeBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(
            interfaceMdId, Modifier.PUBLIC, interfaceType, PhysicalTypeCategory.INTERFACE);
    interfaceTypeBuilder.addAnnotation(interfaceAnnotationMetadata.build());
    typeManagementService.createOrUpdateTypeOnDisk(interfaceTypeBuilder.build());

    // Second build the implementing class
    String classMdId =
        PhysicalTypeIdentifier.createIdentifier(classType, pathResolver.getPath(classIdentifier));
    ClassOrInterfaceTypeDetailsBuilder classTypeBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(
            classMdId, Modifier.PUBLIC, classType, PhysicalTypeCategory.CLASS);
    classTypeBuilder.addImplementsType(interfaceType);
    typeManagementService.createOrUpdateTypeOnDisk(classTypeBuilder.build());
  }
Example #13
0
  /**
   * Generates the "send email" method to be added to the domain type
   *
   * @param mailSenderName the name of the MailSender field (required)
   * @param async whether to send the email asynchronously
   * @param targetClassMID the MID of the class to receive the method
   * @param mutableTypeDetails the type to which the method is being added (required)
   * @return a non-<code>null</code> method
   */
  private MethodMetadata getSendMethod(
      final JavaSymbolName mailSenderName,
      final boolean async,
      final String targetClassMID,
      final ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder) {
    final String contextPath = getApplicationContextPath();
    final Document document = XmlUtils.readXml(fileManager.getInputStream(contextPath));
    final Element root = document.getDocumentElement();

    // Make a builder for the created method's body
    final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();

    // Collect the types and names of the created method's parameters
    final PairList<AnnotatedJavaType, JavaSymbolName> parameters =
        new PairList<AnnotatedJavaType, JavaSymbolName>();

    if (getSimpleMailMessageBean(root) == null) {
      // There's no SimpleMailMessage bean; use a local variable
      bodyBuilder.appendFormalLine(
          "org.springframework.mail.SimpleMailMessage "
              + LOCAL_MESSAGE_VARIABLE
              + " = new org.springframework.mail.SimpleMailMessage();");
      // Set the from address
      parameters.add(STRING, new JavaSymbolName("mailFrom"));
      bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setFrom(mailFrom);");
      // Set the subject
      parameters.add(STRING, new JavaSymbolName("subject"));
      bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setSubject(subject);");
    } else {
      // A SimpleMailMessage bean exists; auto-wire it into the entity and use it as a template
      final List<AnnotationMetadataBuilder> smmAnnotations =
          Arrays.asList(new AnnotationMetadataBuilder(AUTOWIRED));
      final FieldMetadataBuilder smmFieldBuilder =
          new FieldMetadataBuilder(
              targetClassMID,
              PRIVATE_TRANSIENT,
              smmAnnotations,
              new JavaSymbolName(TEMPLATE_MESSAGE_FIELD),
              SIMPLE_MAIL_MESSAGE);
      classOrInterfaceTypeDetailsBuilder.addField(smmFieldBuilder.build());
      // Use the injected bean as a template (for thread safety)
      bodyBuilder.appendFormalLine(
          "org.springframework.mail.SimpleMailMessage "
              + LOCAL_MESSAGE_VARIABLE
              + " = new org.springframework.mail.SimpleMailMessage("
              + TEMPLATE_MESSAGE_FIELD
              + ");");
    }

    // Set the to address
    parameters.add(STRING, new JavaSymbolName("mailTo"));
    bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setTo(mailTo);");

    // Set the message body
    parameters.add(STRING, new JavaSymbolName("message"));
    bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setText(message);");

    bodyBuilder.newLine();
    bodyBuilder.appendFormalLine(mailSenderName + ".send(" + LOCAL_MESSAGE_VARIABLE + ");");

    final MethodMetadataBuilder methodBuilder =
        new MethodMetadataBuilder(
            targetClassMID,
            Modifier.PUBLIC,
            new JavaSymbolName("sendMessage"),
            JavaType.VOID_PRIMITIVE,
            parameters.getKeys(),
            parameters.getValues(),
            bodyBuilder);

    if (async) {
      if (DomUtils.findFirstElementByName("task:annotation-driven", root) == null) {
        // Add asynchronous email support to the application
        if (!StringUtils.hasText(root.getAttribute("xmlns:task"))) {
          // Add the "task" namespace to the Spring config file
          root.setAttribute("xmlns:task", SPRING_TASK_NS);
          root.setAttribute(
              "xsi:schemaLocation",
              root.getAttribute("xsi:schemaLocation")
                  + "  "
                  + SPRING_TASK_NS
                  + " "
                  + SPRING_TASK_XSD);
        }
        root.appendChild(
            new XmlElementBuilder("task:annotation-driven", document)
                .addAttribute("executor", "asyncExecutor")
                .addAttribute("mode", "aspectj")
                .build());
        root.appendChild(
            new XmlElementBuilder("task:executor", document)
                .addAttribute("id", "asyncExecutor")
                .addAttribute("pool-size", "${executor.poolSize}")
                .build());
        // Write out the new Spring config file
        fileManager.createOrUpdateTextFileIfRequired(
            contextPath, XmlUtils.nodeToString(document), false);
        // Update the email properties file
        propFileOperations.addPropertyIfNotExists(
            Path.SPRING_CONFIG_ROOT, "email.properties", "executor.poolSize", "10", true);
      }
      methodBuilder.addAnnotation(new AnnotationMetadataBuilder(ASYNC));
    }
    return methodBuilder.build();
  }
  @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);
  }
  public MetadataItem get(String metadataIdentificationString) {
    ProjectMetadata projectMetadata = projectOperations.getProjectMetadata();
    if (projectMetadata == null) {
      return null;
    }

    ClassOrInterfaceTypeDetails proxy = getGovernor(metadataIdentificationString);
    if (proxy == null) {
      return null;
    }

    AnnotationMetadata proxyAnnotation =
        GwtUtils.getFirstAnnotation(proxy, GwtUtils.PROXY_ANNOTATIONS);
    if (proxyAnnotation == null) {
      return null;
    }

    String locatorType = GwtUtils.getStringValue(proxyAnnotation.getAttribute("locator"));
    if (!StringUtils.hasText(locatorType)) {
      return null;
    }

    ClassOrInterfaceTypeDetails entity = gwtTypeService.lookupEntityFromProxy(proxy);
    if (entity == null) {
      return null;
    }

    MethodMetadata idAccessor = persistenceMemberLocator.getIdentifierAccessor(entity.getName());
    MethodMetadata versionAccessor = persistenceMemberLocator.getVersionAccessor(entity.getName());
    if (idAccessor == null || versionAccessor == null) {
      return null;
    }

    final JavaType idType = GwtUtils.convertPrimitiveType(idAccessor.getReturnType(), true);
    String locatorIdentifier = PhysicalTypeIdentifier.createIdentifier(new JavaType(locatorType));
    ClassOrInterfaceTypeDetailsBuilder locatorBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(locatorIdentifier);
    AnnotationMetadataBuilder annotationMetadataBuilder =
        new AnnotationMetadataBuilder(RooJavaType.ROO_GWT_LOCATOR);
    annotationMetadataBuilder.addStringAttribute(
        "value", entity.getName().getFullyQualifiedTypeName());
    locatorBuilder.addAnnotation(annotationMetadataBuilder);
    annotationMetadataBuilder = new AnnotationMetadataBuilder(SpringJavaType.COMPONENT);
    locatorBuilder.addAnnotation(annotationMetadataBuilder);
    locatorBuilder.setName(new JavaType(locatorType));
    locatorBuilder.setModifier(Modifier.PUBLIC);
    locatorBuilder.setPhysicalTypeCategory(PhysicalTypeCategory.CLASS);
    locatorBuilder.addExtendsTypes(
        new JavaType(
            GwtUtils.LOCATOR.getFullyQualifiedTypeName(),
            0,
            DataType.TYPE,
            null,
            Arrays.asList(entity.getName(), idType)));
    locatorBuilder.addMethod(getCreateMethod(locatorIdentifier, entity.getName()));
    locatorBuilder.addMethod(
        getFindMethod(locatorBuilder, locatorIdentifier, entity.getName(), idType));
    locatorBuilder.addMethod(getDomainTypeMethod(locatorIdentifier, entity.getName()));
    locatorBuilder.addMethod(getIdMethod(locatorIdentifier, entity.getName(), idAccessor));
    locatorBuilder.addMethod(getIdTypeMethod(locatorIdentifier, entity.getName(), idType));
    locatorBuilder.addMethod(
        getVersionMethod(locatorIdentifier, entity.getName(), versionAccessor));

    typeManagementService.createOrUpdateTypeOnDisk(locatorBuilder.build());
    return null;
  }
 public MemberHoldingTypeDetails build() {
   if (existing instanceof ItdTypeDetails) {
     ItdTypeDetailsBuilder builder = new ItdTypeDetailsBuilder((ItdTypeDetails) existing);
     // Push in all members that may have been modified
     builder.setDeclaredFields(this.getDeclaredFields());
     builder.setDeclaredMethods(this.getDeclaredMethods());
     builder.setAnnotations(this.getAnnotations());
     builder.setCustomData(this.getCustomData());
     builder.setDeclaredConstructors(this.getDeclaredConstructors());
     builder.setDeclaredInitializers(this.getDeclaredInitializers());
     builder.setDeclaredInnerTypes(this.getDeclaredInnerTypes());
     builder.setExtendsTypes(this.getExtendsTypes());
     builder.setImplementsTypes(this.getImplementsTypes());
     builder.setModifier(this.getModifier());
     return builder.build();
   } else if (existing instanceof ClassOrInterfaceTypeDetails) {
     ClassOrInterfaceTypeDetailsBuilder builder =
         new ClassOrInterfaceTypeDetailsBuilder((ClassOrInterfaceTypeDetails) existing);
     // Push in all members that may
     builder.setDeclaredFields(this.getDeclaredFields());
     builder.setDeclaredMethods(this.getDeclaredMethods());
     builder.setAnnotations(this.getAnnotations());
     builder.setCustomData(this.getCustomData());
     builder.setDeclaredConstructors(this.getDeclaredConstructors());
     builder.setDeclaredInitializers(this.getDeclaredInitializers());
     builder.setDeclaredInnerTypes(this.getDeclaredInnerTypes());
     builder.setExtendsTypes(this.getExtendsTypes());
     builder.setImplementsTypes(this.getImplementsTypes());
     builder.setModifier(this.getModifier());
     return builder.build();
   } else {
     throw new IllegalStateException("Unknown instance of MemberHoldingTypeDetails");
   }
 }
  private Table updateOrDeleteManagedEntity(
      final ClassOrInterfaceTypeDetails managedEntity, final Database database) {
    // Update the attributes of the existing JPA-related annotation
    final AnnotationMetadata jpaAnnotation = getJpaAnnotation(managedEntity);
    Validate.validState(
        jpaAnnotation != null,
        "Neither @%s nor @%s found on existing DBRE-managed entity %s",
        ROO_JPA_ACTIVE_RECORD.getSimpleTypeName(),
        ROO_JPA_ENTITY.getSimpleTypeName(),
        managedEntity.getName().getFullyQualifiedTypeName());

    // Find table in database using 'table' and 'schema' attributes from the
    // JPA annotation
    final AnnotationAttributeValue<?> tableAttribute =
        jpaAnnotation.getAttribute(new JavaSymbolName("table"));
    final String errMsg =
        "Unable to maintain database-managed entity "
            + managedEntity.getName().getFullyQualifiedTypeName()
            + " because its associated table could not be found";
    Validate.notNull(tableAttribute, errMsg);
    final String tableName = (String) tableAttribute.getValue();
    Validate.notBlank(tableName, errMsg);

    final AnnotationAttributeValue<?> schemaAttribute =
        jpaAnnotation.getAttribute(new JavaSymbolName("schema"));
    final String schemaName = schemaAttribute != null ? (String) schemaAttribute.getValue() : null;

    final Table table = database.getTable(tableName, schemaName);
    if (table == null) {
      // Table is missing and probably has been dropped so delete managed
      // type and its identifier if applicable
      deleteManagedType(managedEntity, "no database table called '" + tableName + "'");
      return null;
    }

    table.setIncludeNonPortableAttributes(database.isIncludeNonPortableAttributes());
    table.setDisableVersionFields(database.isDisableVersionFields());
    table.setDisableGeneratedIdentifiers(database.isDisableGeneratedIdentifiers());

    // Update the @RooJpaEntity/@RooJpaActiveRecord attributes
    final AnnotationMetadataBuilder jpaAnnotationBuilder =
        new AnnotationMetadataBuilder(jpaAnnotation);
    final Set<JavaSymbolName> attributesToDeleteIfPresent = new LinkedHashSet<JavaSymbolName>();
    manageIdentifier(
        managedEntity.getName(), jpaAnnotationBuilder, attributesToDeleteIfPresent, table);

    // Manage versionField attribute
    final AnnotationAttributeValue<?> versionFieldAttribute =
        jpaAnnotation.getAttribute(new JavaSymbolName(VERSION_FIELD));
    if (versionFieldAttribute == null) {
      if (hasVersionField(table)) {
        attributesToDeleteIfPresent.add(new JavaSymbolName(VERSION_FIELD));
      } else {
        jpaAnnotationBuilder.addStringAttribute(VERSION_FIELD, "");
      }
    } else {
      final String versionFieldValue = (String) versionFieldAttribute.getValue();
      if (hasVersionField(table)
          && (StringUtils.isBlank(versionFieldValue) || VERSION.equals(versionFieldValue))) {
        attributesToDeleteIfPresent.add(new JavaSymbolName(VERSION_FIELD));
      }
    }

    final AnnotationAttributeValue<?> sequenceNameFieldAttribute =
        jpaAnnotation.getAttribute(new JavaSymbolName(SEQUENCE_NAME_FIELD));
    if (sequenceNameFieldAttribute == null) {
      if (!table.isDisableGeneratedIdentifiers()) {
        attributesToDeleteIfPresent.add(new JavaSymbolName(SEQUENCE_NAME_FIELD));
      } else {
        jpaAnnotationBuilder.addStringAttribute(SEQUENCE_NAME_FIELD, "");
      }
    } else {
      final String sequenceNameFieldValue = (String) sequenceNameFieldAttribute.getValue();
      if (!table.isDisableGeneratedIdentifiers() && ("".equals(sequenceNameFieldValue))) {
        attributesToDeleteIfPresent.add(new JavaSymbolName(SEQUENCE_NAME_FIELD));
      }
    }

    // Update the annotation on disk
    final ClassOrInterfaceTypeDetailsBuilder cidBuilder =
        new ClassOrInterfaceTypeDetailsBuilder(managedEntity);
    cidBuilder.updateTypeAnnotation(jpaAnnotationBuilder.build(), attributesToDeleteIfPresent);
    typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
    return table;
  }