@Override
  public void layout(
      final String name,
      final Dimension height,
      final Dimension width,
      final Orientation orientation) {
    final Document document = newDocumentBuilder().newDocument();

    final Element layoutElem = document.createElement("LinearLayout");
    layoutElem.setAttribute("xmlns:android", ANDROID_NS);
    layoutElem.setAttribute("android:layout_height", height.value());
    layoutElem.setAttribute("android:layout_width", width.value());
    layoutElem.setAttribute("android:orientation", orientation.value());
    document.appendChild(layoutElem);

    final String layoutPath =
        pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + name + XML_EXTENSION);
    if (fileManager.exists(layoutPath)) {
      LOGGER.severe("Layout '" + name + "' already exists");
      return;
    }
    final MutableFile file = fileManager.createFile(layoutPath);
    final OutputStream output = file.getOutputStream();
    XmlUtils.writeFormattedXml(output, document);
    try {
      output.close();
    } catch (IOException e) {
      LOGGER.severe("Error closing stream: " + e.getMessage());
      return;
    }
    //        fileManager.createOrUpdateTextFileIfRequired(layoutPath,
    //                XmlUtils.nodeToString(document), true);
  }
  private void modifyTags() {
    // TODO modify tags instead of overwriting them!!!
    String targetPath =
        pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/tags/form/fields");

    LOG.info("disabled copying of tags");
    // copyDirectoryContents("tags/*.*", targetPath, true);
  }
  public void setup() {
    if (hasDotGit()) {
      LOGGER.info("Git is already configured");
      return;
    }
    if (person == null) {
      person = new PersonIdent("Roo Git Add-On", "*****@*****.**");
    }
    try {
      final String repositoryPath = pathResolver.getFocusedIdentifier(Path.ROOT, Constants.DOT_GIT);
      final Repository repository =
          new FileRepositoryBuilder().readEnvironment().setGitDir(new File(repositoryPath)).build();
      repository.create();
    } catch (final Exception e) {
      throw new IllegalStateException("Could not initialize Git repository", e);
    }
    setConfig("user", "name", person.getName());
    setConfig("user", "email", person.getEmailAddress());

    setConfig("remote \"origin\"", "fetch", "+refs/heads/*:refs/remotes/origin/*");
    setConfig("branch \"master\"", "remote", "origin");
    setConfig("branch \"master\"", "merge", "refs/heads/master");

    final String gitIgnore =
        pathResolver.getFocusedIdentifier(Path.ROOT, Constants.GITIGNORE_FILENAME);

    if (!fileManager.exists(gitIgnore)) {
      InputStream inputStream = null;
      OutputStream outputStream = null;
      try {
        inputStream = FileUtils.getInputStream(getClass(), "gitignore-template");
        outputStream = fileManager.createFile(gitIgnore).getOutputStream();
        IOUtils.copy(inputStream, outputStream);
      } catch (final IOException e) {
        throw new IllegalStateException(
            "Could not install " + Constants.GITIGNORE_FILENAME + " file in project", e);
      } finally {
        IOUtils.closeQuietly(inputStream);
        IOUtils.closeQuietly(outputStream);
      }
    }
  }
  private Connection getConnection(final boolean displayAddOns) {
    if (fileManager.exists(
        pathResolver.getFocusedIdentifier(Path.SPRING_CONFIG_ROOT, "database.properties"))) {
      Map<String, String> connectionProperties =
          propFileOperations.getProperties(
              Path.SPRING_CONFIG_ROOT.contextualize(projectOperations.getFocusedModuleName()),
              "database.properties");
      return connectionProvider.getConnection(connectionProperties, displayAddOns);
    }

    Properties connectionProperties = getConnectionPropertiesFromDataNucleusConfiguration();
    return connectionProvider.getConnection(connectionProperties, displayAddOns);
  }
  @Override
  public void setup() {
    if (!fileManager.exists(
        projectOperations
            .getPathResolver()
            .getFocusedIdentifier(SRC_MAIN_WEBAPP, "WEB-INF/web.xml"))) {
      webMvcOperations.installAllWebMvcArtifacts();
    }

    final Element configuration = XmlUtils.getConfiguration(getClass());

    for (Element propertyElement :
        XmlUtils.findElements("/configuration/batch/properties/*", configuration)) {
      projectOperations.addProperty(
          projectOperations.getFocusedModuleName(), new Property(propertyElement));
    }

    final List<Dependency> dependencies = new ArrayList<Dependency>();
    for (final Element dependencyElement :
        XmlUtils.findElements("/configuration/batch/dependencies/*", configuration)) {
      dependencies.add(new Dependency(dependencyElement));
    }
    projectOperations.removeDependencies(projectOperations.getFocusedModuleName(), dependencies);
    metadataService.evict(
        ProjectMetadata.getProjectIdentifier(projectOperations.getFocusedModuleName()));
    projectOperations.addDependencies(projectOperations.getFocusedModuleName(), dependencies);

    final String webConfigFile =
        pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, WEBMVC_CONFIG_XML);
    Validate.isTrue(fileManager.exists(webConfigFile), "Aborting: Unable to find " + webConfigFile);
    InputStream webMvcConfigInputStream = null;
    try {
      webMvcConfigInputStream = fileManager.getInputStream(webConfigFile);
      Validate.notNull(
          webMvcConfigInputStream, "Aborting: Unable to acquire webmvc-config.xml file");
      final Document webMvcConfig = XmlUtils.readXml(webMvcConfigInputStream);
      final Element root = webMvcConfig.getDocumentElement();
      if (XmlUtils.findFirstElement("/beans/bean[@class='" + REST_MVC_CONFIG + "']", root)
          == null) {
        final Element config = webMvcConfig.createElement("bean");
        config.setAttribute("class", REST_MVC_CONFIG);
        root.appendChild(config);

        fileManager.createOrUpdateTextFileIfRequired(
            webConfigFile, XmlUtils.nodeToString(webMvcConfig), true);
      }
    } finally {
      IOUtils.closeQuietly(webMvcConfigInputStream);
    }
  }
 private Repository getRepository() {
   if (hasDotGit()) {
     try {
       final String repositoryPath =
           pathResolver.getFocusedIdentifier(Path.ROOT, Constants.DOT_GIT);
       return new FileRepositoryBuilder()
           .readEnvironment()
           .findGitDir(new File(repositoryPath))
           .build();
     } catch (final IOException e) {
       throw new IllegalStateException(e);
     }
   }
   throw new IllegalStateException("Git support not available");
 }
  @Override
  public void resourceString(
      final JavaType type, final String name, final JavaSymbolName fieldName, final String value) {

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

    final DocumentBuilder builder = newDocumentBuilder();
    final String valuesPath =
        pathResolver.getFocusedIdentifier(Path.ROOT, VALUES_PATH + SEP + STRINGS + XML_EXTENSION);

    InputStream inputStream = null;
    Document document = null;
    try {
      inputStream = fileManager.getInputStream(valuesPath);
      document = builder.parse(inputStream);
    } catch (final Exception e) {
      LOGGER.severe("Error reading resource XML: " + e.getMessage());
    } finally {
      IOUtils.closeQuietly(inputStream);
    }

    if (document != null) {
      final Element root = document.getDocumentElement();

      final Element stringElem = XmlUtils.createTextElement(document, "string", value);
      final String id = StringUtils.isEmpty(name) ? fieldName.getSymbolName() : name;
      stringElem.setAttribute("name", id);
      root.appendChild(stringElem);

      fileManager.createOrUpdateTextFileIfRequired(
          valuesPath, XmlUtils.nodeToString(document), true);
    }

    final String physicalTypeIdentifier = typeDetails.getDeclaredByMetadataId();

    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    final AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(ROO_STRING);
    if (!StringUtils.isEmpty(name)) {
      annotationBuilder.addStringAttribute("value", name);
    }
    annotations.add(annotationBuilder);

    final FieldMetadataBuilder fieldBuilder =
        new FieldMetadataBuilder(physicalTypeIdentifier, 0, annotations, fieldName, STRING);
    typeManagementService.addField(fieldBuilder.build());
  }
  private Properties getConnectionPropertiesFromDataNucleusConfiguration() {
    String persistenceXmlPath =
        pathResolver.getFocusedIdentifier(Path.SRC_MAIN_RESOURCES, "META-INF/persistence.xml");
    if (!fileManager.exists(persistenceXmlPath)) {
      throw new IllegalStateException("Failed to find " + persistenceXmlPath);
    }

    FileDetails fileDetails = fileManager.readFile(persistenceXmlPath);
    Document document = null;
    try {
      InputStream is = new BufferedInputStream(new FileInputStream(fileDetails.getFile()));
      DocumentBuilder builder = XmlUtils.getDocumentBuilder();
      builder.setErrorHandler(null);
      document = builder.parse(is);
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }

    List<Element> propertyElements =
        XmlUtils.findElements(
            "/persistence/persistence-unit/properties/property", document.getDocumentElement());
    Assert.notEmpty(propertyElements, "Failed to find property elements in " + persistenceXmlPath);
    Properties properties = new Properties();

    for (Element propertyElement : propertyElements) {
      String key = propertyElement.getAttribute("name");
      String value = propertyElement.getAttribute("value");
      if ("datanucleus.ConnectionDriverName".equals(key)) {
        properties.put("database.driverClassName", value);
      }
      if ("datanucleus.ConnectionURL".equals(key)) {
        properties.put("database.url", value);
      }
      if ("datanucleus.ConnectionUserName".equals(key)) {
        properties.put("database.username", value);
      }
      if ("datanucleus.ConnectionPassword".equals(key)) {
        properties.put("database.password", value);
      }

      if (properties.size() == 4) {
        // All required properties have been found so ignore rest of elements
        break;
      }
    }
    return properties;
  }
  @Override
  public void activity(
      final JavaType name,
      final String layout,
      final boolean main,
      final boolean noTitle,
      final boolean fullscreen) {
    if (noTitle) {
      Validate.isTrue(fullscreen == false, "Options 'noTitle' and 'fullscreen' are mutex");
    }
    if (fullscreen) {
      Validate.isTrue(noTitle == false, "Options 'noTitle' and 'fullscreen' are mutex");
    }

    if (!StringUtils.isEmpty(layout)) {
      final String layoutPath =
          pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION);
      if (!fileManager.exists(layoutPath)) {
        LOGGER.info("Layout '" + layout + "' does not exist");
        layout(layout, Dimension.FILL_PARENT, Dimension.FILL_PARENT, Orientation.VERTICAL);
      }
    }

    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    final AnnotationMetadataBuilder activityAnnotationBuilder =
        new AnnotationMetadataBuilder(ROO_ACTIVITY);
    if (!StringUtils.isEmpty(layout)) {
      activityAnnotationBuilder.addStringAttribute("value", layout);
    }
    if (noTitle) {
      activityAnnotationBuilder.addBooleanAttribute(RooActivity.NO_TITLE_ATTRIBUTE, noTitle);
    }
    if (fullscreen) {
      activityAnnotationBuilder.addBooleanAttribute(RooActivity.FULLSCREEN_ATTRIBUTE, fullscreen);
    }
    annotations.add(activityAnnotationBuilder);

    jpaOperations.newEntity(name, false, ANDROID_ACTIVITY, annotations);

    androidTypeService.addActvity(
        projectOperations.getFocusedModuleName(), name.getFullyQualifiedTypeName(), main);
  }
 @Override
 public boolean isInstalledInModule(String moduleName) {
   final String webConfigFile =
       pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, WEBMVC_CONFIG_XML);
   if (!fileManager.exists(webConfigFile)) {
     return false;
   }
   InputStream webMvcConfigInputStream = null;
   try {
     webMvcConfigInputStream = fileManager.getInputStream(webConfigFile);
     if (webMvcConfigInputStream == null) {
       return false;
     }
     final Document webMvcConfig = XmlUtils.readXml(webMvcConfigInputStream);
     final Element root = webMvcConfig.getDocumentElement();
     return XmlUtils.findFirstElement("/beans/bean[@class='" + REST_MVC_CONFIG + "']", root)
         != null;
   } finally {
     IOUtils.closeQuietly(webMvcConfigInputStream);
   }
 }
  @Override
  public void fragment(final JavaType name, final String layout, final boolean support) {

    if (!StringUtils.isEmpty(layout)) {
      final String layoutPath =
          pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION);
      if (!fileManager.exists(layoutPath)) {
        LOGGER.info("Layout '" + layout + "' does not exist");
        layout(layout, Dimension.FILL_PARENT, Dimension.FILL_PARENT, Orientation.VERTICAL);
      }
    }

    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    final AnnotationMetadataBuilder activityAnnotationBuilder =
        new AnnotationMetadataBuilder(ROO_FRAGMENT);
    if (!StringUtils.isEmpty(layout)) {
      activityAnnotationBuilder.addStringAttribute("value", layout);
    }
    annotations.add(activityAnnotationBuilder);

    jpaOperations.newEntity(
        name, false, support ? ANDROID_SUPPORT_FRAGMENT : ANDROID_FRAGMENT, annotations);
  }
 public void addViews(final JavaType type) {
   String targetPath = pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/views/");
   EnversViewManager viewManager = new EnversViewManager(type, targetPath);
   viewManager.addViews();
 }
 private boolean hasDotGit() {
   return fileManager.exists(pathResolver.getFocusedIdentifier(Path.ROOT, Constants.DOT_GIT));
 }
  @Override
  public void view(
      final JavaType type,
      final String viewName,
      final String identifier,
      final JavaSymbolName fieldName,
      final Dimension height,
      final Dimension width) {

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

    final JavaType viewType =
        new JavaType(viewName.contains(".") ? viewName : WIDGET_PACKAGE + "." + viewName);

    final String layout =
        RequestFactoryUtils.getStringAnnotationValue(typeDetails, ROO_ACTIVITY, "value", "");
    if (!StringUtils.isEmpty(layout)) {
      final DocumentBuilder builder = newDocumentBuilder();
      final String layoutPath =
          pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION);

      InputStream inputStream = null;
      Document document = null;
      try {
        inputStream = fileManager.getInputStream(layoutPath);
        document = builder.parse(inputStream);
      } catch (final Exception e) {
        LOGGER.severe("Error reading layout XML: " + e.getMessage());
      } finally {
        IOUtils.closeQuietly(inputStream);
      }

      if (document != null) {
        final Element root = document.getDocumentElement();

        final Element viewElem = document.createElement(viewType.getSimpleTypeName());
        final String id = StringUtils.isEmpty(identifier) ? fieldName.getSymbolName() : identifier;
        viewElem.setAttribute("android:id", ID_PREFIX + id);
        viewElem.setAttribute("android:layout_height", height.value());
        viewElem.setAttribute("android:layout_width", width.value());
        root.appendChild(viewElem);

        fileManager.createOrUpdateTextFileIfRequired(
            layoutPath, XmlUtils.nodeToString(document), true);
      }
    }

    final String physicalTypeIdentifier = typeDetails.getDeclaredByMetadataId();

    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    final AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(ROO_VIEW);
    if (!StringUtils.isEmpty(identifier)) {
      annotationBuilder.addStringAttribute("value", identifier);
    }
    annotations.add(annotationBuilder);

    final FieldMetadataBuilder fieldBuilder =
        new FieldMetadataBuilder(physicalTypeIdentifier, 0, annotations, fieldName, viewType);
    typeManagementService.addField(fieldBuilder.build());
  }
 public String getDbreXmlPath() {
   return projectOperations.isFocusedProjectAvailable()
       ? pathResolver.getFocusedIdentifier(Path.SRC_MAIN_RESOURCES, DbreModelService.DBRE_XML)
       : null;
 }