<commit_before>package org.jboss.forge.addon.projects.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;

import org.jboss.forge.addon.convert.Converter;
import org.jboss.forge.addon.projects.BuildSystem;
import org.jboss.forge.addon.projects.BuildSystemFacet;
import org.jboss.forge.addon.projects.Project;
import org.jboss.forge.addon.projects.ProjectFacet;
import org.jboss.forge.addon.projects.ProjectFactory;
import org.jboss.forge.addon.projects.ProjectType;
import org.jboss.forge.addon.projects.facets.MetadataFacet;
import org.jboss.forge.addon.resource.DirectoryResource;
import org.jboss.forge.addon.resource.Resource;
import org.jboss.forge.addon.resource.ResourceFactory;
import org.jboss.forge.addon.ui.UIValidator;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIContext;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.context.UISelection;
import org.jboss.forge.addon.ui.context.UIValidationContext;
import org.jboss.forge.addon.ui.input.SingleValued;
import org.jboss.forge.addon.ui.input.UIInput;
import org.jboss.forge.addon.ui.input.UISelectOne;
import org.jboss.forge.addon.ui.metadata.UICommandMetadata;
import org.jboss.forge.addon.ui.metadata.WithAttributes;
import org.jboss.forge.addon.ui.result.NavigationResult;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;
import org.jboss.forge.addon.ui.util.Categories;
import org.jboss.forge.addon.ui.util.Metadata;
import org.jboss.forge.addon.ui.wizard.UIWizard;
import org.jboss.forge.furnace.services.Imported;
import org.jboss.forge.furnace.util.OperatingSystemUtils;

public class NewProjectWizard implements UIWizard
{
   private static final Logger log = Logger.getLogger(NewProjectWizard.class.getName());

   @Inject
   private ProjectFactory projectFactory;

   @Inject
   private ResourceFactory resourceFactory;

   @Inject
   private Imported<BuildSystem> buildSystems;

   @Inject
   @WithAttributes(label = "Project name:", required = true)
   private UIInput<String> named;

   @Inject
   @WithAttributes(label = "Top level package:")
   private UIInput<String> topLevelPackage;

   @Inject
   @WithAttributes(label = "Version:", required = false)
   private UIInput<String> version;

   @Inject
   @WithAttributes(label = "Project location:")
   private UIInput<DirectoryResource> targetLocation;

   @Inject
   @WithAttributes(label = "Overwrite existing project location")
   private UIInput<Boolean> overwrite;

   @Inject
   @WithAttributes(label = "Project Type:", required = true)
   private UISelectOne<ProjectType> type;

   @Inject
   @WithAttributes(label = "Build System:", required = true)
   private UISelectOne<BuildSystem> buildSystem;

   @Override
   public UICommandMetadata getMetadata(UIContext context)
   {
      return Metadata.forCommand(getClass()).name("New Project").description("Create a new project")
               .category(Categories.create("Project", "Generation"));
   }

   @Override
   public boolean isEnabled(UIContext context)
   {
      return buildSystem.getValueChoices().iterator().hasNext();
   }

   @Override
   public void initializeUI(final UIBuilder builder) throws Exception
   {
      configureProjectNamedInput();
      configureVersionInput();
      configureTargetLocationInput(builder);
      configureOverwriteInput();
      configureProjectTypeInput(builder);
      configureTopLevelPackageInput();
      configureBuildSystemInput();

      builder.add(named).add(topLevelPackage).add(version).add(targetLocation).add(overwrite).add(type)
               .add(buildSystem);
   }

   private void configureProjectNamedInput()
   {
      named.setValidator(new UIValidator()
      {
         @Override
         public void validate(UIValidationContext context)
         {
            if (named.getValue() != null && named.getValue().matches(".*[^-_.a-zA-Z0-9].*"))
               context.addValidationError(named, "Project name must not contain spaces or special characters.");
         }
      });
   }

   private void configureVersionInput()
   {
      version.setDefaultValue("1.0.0-SNAPSHOT");
   }

   private void configureTargetLocationInput(final UIBuilder builder)
   {
      UISelection<Resource<?>> currentSelection = builder.getUIContext().getInitialSelection();
      if (!currentSelection.isEmpty())
      {
         Resource<?> resource = currentSelection.get();
         if (resource instanceof DirectoryResource)
         {
            targetLocation.setDefaultValue((DirectoryResource) resource);
         }
      }
      else
      {
         targetLocation.setDefaultValue(resourceFactory.create(DirectoryResource.class,
                  OperatingSystemUtils.getUserHomeDir()));
      }
   }

   private void configureOverwriteInput()
   {
      overwrite.setDefaultValue(false).setEnabled(new Callable<Boolean>()
      {
         @Override
         public Boolean call() throws Exception
         {
            String projectName = named.getValue();
            return targetLocation.getValue() != null && projectName != null
                     && targetLocation.getValue().getChild(projectName).exists()
                     && !targetLocation.getValue().getChild(projectName).listResources().isEmpty();
         }
      });
   }

   private void configureProjectTypeInput(final UIBuilder builder)
   {
      if (builder.getUIContext().getProvider().isGUI())
      {
         type.setItemLabelConverter(new Converter<ProjectType, String>()
         {
            @Override
            public String convert(ProjectType source)
            {
               return source == null ? null : source.getType();
            }
         });
      }

      // Add Project types
      List<ProjectType> projectTypes = new ArrayList<ProjectType>();
      for (ProjectType projectType : type.getValueChoices())
      {
         boolean buildable = false;
         for (BuildSystem buildSystem : buildSystems)
         {
            if (isProjectTypeBuildable(projectType, buildSystem))
            {
               projectTypes.add(projectType);
               buildable = true;
               break;
            }
         }

         if (!buildable)
            log.log(Level.FINE, "ProjectType [" + projectType.getType() + "] "
                     + "deactivated because it cannot be built with any registered BuildSystem instances ["
                     + buildSystems + "].");
      }

      Collections.sort(projectTypes, new Comparator<ProjectType>()
      {
         @Override
         public int compare(ProjectType left, ProjectType right)
         {
            return new Integer(left.priority()).compareTo(right.priority());
         }
      });

      if (!projectTypes.isEmpty())
      {
         type.setDefaultValue(projectTypes.get(0));
      }
      type.setValueChoices(projectTypes);
   }

   private void configureTopLevelPackageInput()
   {
      topLevelPackage.setDefaultValue(new Callable<String>()
      {
         @Override
         public String call() throws Exception
         {
            String result = named.getValue();
            if (result != null)
            {
               result = ("org." + result).replaceAll("\\W+", ".");
               result = result.trim();
               result = result.replaceAll("^\\.", "");
               result = result.replaceAll("\\.$", "");
            }
            else
               result = "org.example";
            return result;
         }
      });
   }

   private void configureBuildSystemInput()
   {
      buildSystem.setRequired(true);
      buildSystem.setItemLabelConverter(new Converter<BuildSystem, String>()
      {
         @Override
         public String convert(BuildSystem source)
         {
            return source == null ? null : source.getType();
         }
      });

      buildSystem.setValueChoices(new Callable<Iterable<BuildSystem>>()
      {
         @Override
         public Iterable<BuildSystem> call() throws Exception
         {
            List<BuildSystem> result = new ArrayList<BuildSystem>();
            for (BuildSystem buildSystemType : buildSystems)
            {
               ProjectType projectType = type.getValue();
               if (projectType != null)
               {
                  if (isProjectTypeBuildable(projectType, buildSystemType))
                     result.add(buildSystemType);
               }
               else
                  result.add(buildSystemType);
            }

            Collections.sort(result, new Comparator<BuildSystem>()
            {
               @Override
               public int compare(BuildSystem left, BuildSystem right)
               {
                  return new Integer(left.priority()).compareTo(right.priority());
               }
            });

            return result;
         }
      });

      buildSystem.setDefaultValue(new Callable<BuildSystem>()
      {
         @Override
         public BuildSystem call() throws Exception
         {
            if (buildSystem.getValueChoices().iterator().hasNext())
            {
               return buildSystem.getValueChoices().iterator().next();
            }
            return null;
         }
      });
   }

   private boolean isProjectTypeBuildable(ProjectType type, BuildSystem buildSystem)
   {
      boolean result = false;
      Iterable<Class<? extends BuildSystemFacet>> requiredFacets = getRequiredBuildSystemFacets(type);
      if (requiredFacets == null || !requiredFacets.iterator().hasNext())
      {
         result = true;
      }
      else
      {
         for (Class<? extends BuildSystemFacet> required : requiredFacets)
         {
            result = false;
            for (Class<? extends BuildSystemFacet> provided : buildSystem.getProvidedFacetTypes())
            {
               if (provided.isAssignableFrom(required))
                  result = true;
            }
            if (!result)
               break;
         }
      }
      return result;
   }

   @SuppressWarnings("unchecked")
   private Iterable<Class<? extends BuildSystemFacet>> getRequiredBuildSystemFacets(ProjectType type)
   {
      Set<Class<? extends BuildSystemFacet>> result = new HashSet<Class<? extends BuildSystemFacet>>();
      Iterable<Class<? extends ProjectFacet>> requiredFacets = type.getRequiredFacets();
      if (requiredFacets != null)
      {
         for (Class<? extends ProjectFacet> facetType : requiredFacets)
         {
            if (BuildSystemFacet.class.isAssignableFrom(facetType))
            {
               result.add((Class<? extends BuildSystemFacet>) facetType);
            }
         }
      }
      return result;
   }
<commit_msg>Fixed FORGE-1330 - Rename new project command<commit_after>package org.jboss.forge.addon.projects.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;

import org.jboss.forge.addon.convert.Converter;
import org.jboss.forge.addon.projects.BuildSystem;
import org.jboss.forge.addon.projects.BuildSystemFacet;
import org.jboss.forge.addon.projects.Project;
import org.jboss.forge.addon.projects.ProjectFacet;
import org.jboss.forge.addon.projects.ProjectFactory;
import org.jboss.forge.addon.projects.ProjectType;
import org.jboss.forge.addon.projects.facets.MetadataFacet;
import org.jboss.forge.addon.resource.DirectoryResource;
import org.jboss.forge.addon.resource.Resource;
import org.jboss.forge.addon.resource.ResourceFactory;
import org.jboss.forge.addon.ui.UIValidator;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIContext;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.context.UISelection;
import org.jboss.forge.addon.ui.context.UIValidationContext;
import org.jboss.forge.addon.ui.input.SingleValued;
import org.jboss.forge.addon.ui.input.UIInput;
import org.jboss.forge.addon.ui.input.UISelectOne;
import org.jboss.forge.addon.ui.metadata.UICommandMetadata;
import org.jboss.forge.addon.ui.metadata.WithAttributes;
import org.jboss.forge.addon.ui.result.NavigationResult;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;
import org.jboss.forge.addon.ui.util.Categories;
import org.jboss.forge.addon.ui.util.Metadata;
import org.jboss.forge.addon.ui.wizard.UIWizard;
import org.jboss.forge.furnace.services.Imported;
import org.jboss.forge.furnace.util.OperatingSystemUtils;

public class NewProjectWizard implements UIWizard
{
   private static final Logger log = Logger.getLogger(NewProjectWizard.class.getName());

   @Inject
   private ProjectFactory projectFactory;

   @Inject
   private ResourceFactory resourceFactory;

   @Inject
   private Imported<BuildSystem> buildSystems;

   @Inject
   @WithAttributes(label = "Project name:", required = true)
   private UIInput<String> named;

   @Inject
   @WithAttributes(label = "Top level package:")
   private UIInput<String> topLevelPackage;

   @Inject
   @WithAttributes(label = "Version:", required = false)
   private UIInput<String> version;

   @Inject
   @WithAttributes(label = "Project location:")
   private UIInput<DirectoryResource> targetLocation;

   @Inject
   @WithAttributes(label = "Overwrite existing project location")
   private UIInput<Boolean> overwrite;

   @Inject
   @WithAttributes(label = "Project Type:", required = true)
   private UISelectOne<ProjectType> type;

   @Inject
   @WithAttributes(label = "Build System:", required = true)
   private UISelectOne<BuildSystem> buildSystem;

   @Override
   public UICommandMetadata getMetadata(UIContext context)
   {
      return Metadata.forCommand(getClass()).name("Project: New").description("Create a new project")
               .category(Categories.create("Project", "Generation"));
   }

   @Override
   public boolean isEnabled(UIContext context)
   {
      return buildSystem.getValueChoices().iterator().hasNext();
   }

   @Override
   public void initializeUI(final UIBuilder builder) throws Exception
   {
      configureProjectNamedInput();
      configureVersionInput();
      configureTargetLocationInput(builder);
      configureOverwriteInput();
      configureProjectTypeInput(builder);
      configureTopLevelPackageInput();
      configureBuildSystemInput();

      builder.add(named).add(topLevelPackage).add(version).add(targetLocation).add(overwrite).add(type)
               .add(buildSystem);
   }

   private void configureProjectNamedInput()
   {
      named.setValidator(new UIValidator()
      {
         @Override
         public void validate(UIValidationContext context)
         {
            if (named.getValue() != null && named.getValue().matches(".*[^-_.a-zA-Z0-9].*"))
               context.addValidationError(named, "Project name must not contain spaces or special characters.");
         }
      });
   }

   private void configureVersionInput()
   {
      version.setDefaultValue("1.0.0-SNAPSHOT");
   }

   private void configureTargetLocationInput(final UIBuilder builder)
   {
      UISelection<Resource<?>> currentSelection = builder.getUIContext().getInitialSelection();
      if (!currentSelection.isEmpty())
      {
         Resource<?> resource = currentSelection.get();
         if (resource instanceof DirectoryResource)
         {
            targetLocation.setDefaultValue((DirectoryResource) resource);
         }
      }
      else
      {
         targetLocation.setDefaultValue(resourceFactory.create(DirectoryResource.class,
                  OperatingSystemUtils.getUserHomeDir()));
      }
   }

   private void configureOverwriteInput()
   {
      overwrite.setDefaultValue(false).setEnabled(new Callable<Boolean>()
      {
         @Override
         public Boolean call() throws Exception
         {
            String projectName = named.getValue();
            return targetLocation.getValue() != null && projectName != null
                     && targetLocation.getValue().getChild(projectName).exists()
                     && !targetLocation.getValue().getChild(projectName).listResources().isEmpty();
         }
      });
   }

   private void configureProjectTypeInput(final UIBuilder builder)
   {
      if (builder.getUIContext().getProvider().isGUI())
      {
         type.setItemLabelConverter(new Converter<ProjectType, String>()
         {
            @Override
            public String convert(ProjectType source)
            {
               return source == null ? null : source.getType();
            }
         });
      }

      // Add Project types
      List<ProjectType> projectTypes = new ArrayList<>();
      for (ProjectType projectType : type.getValueChoices())
      {
         boolean buildable = false;
         for (BuildSystem buildSystem : buildSystems)
         {
            if (isProjectTypeBuildable(projectType, buildSystem))
            {
               projectTypes.add(projectType);
               buildable = true;
               break;
            }
         }

         if (!buildable)
            log.log(Level.FINE, "ProjectType [" + projectType.getType() + "] "
                     + "deactivated because it cannot be built with any registered BuildSystem instances ["
                     + buildSystems + "].");
      }

      Collections.sort(projectTypes, new Comparator<ProjectType>()
      {
         @Override
         public int compare(ProjectType left, ProjectType right)
         {
            return new Integer(left.priority()).compareTo(right.priority());
         }
      });

      if (!projectTypes.isEmpty())
      {
         type.setDefaultValue(projectTypes.get(0));
      }
      type.setValueChoices(projectTypes);
   }

   private void configureTopLevelPackageInput()
   {
      topLevelPackage.setDefaultValue(new Callable<String>()
      {
         @Override
         public String call() throws Exception
         {
            String result = named.getValue();
            if (result != null)
            {
               result = ("org." + result).replaceAll("\\W+", ".");
               result = result.trim();
               result = result.replaceAll("^\\.", "");
               result = result.replaceAll("\\.$", "");
            }
            else
               result = "org.example";
            return result;
         }
      });
   }

   private void configureBuildSystemInput()
   {
      buildSystem.setRequired(true);
      buildSystem.setItemLabelConverter(new Converter<BuildSystem, String>()
      {
         @Override
         public String convert(BuildSystem source)
         {
            return source == null ? null : source.getType();
         }
      });

      buildSystem.setValueChoices(new Callable<Iterable<BuildSystem>>()
      {
         @Override
         public Iterable<BuildSystem> call() throws Exception
         {
            List<BuildSystem> result = new ArrayList<>();
            for (BuildSystem buildSystemType : buildSystems)
            {
               ProjectType projectType = type.getValue();
               if (projectType != null)
               {
                  if (isProjectTypeBuildable(projectType, buildSystemType))
                     result.add(buildSystemType);
               }
               else
                  result.add(buildSystemType);
            }

            Collections.sort(result, new Comparator<BuildSystem>()
            {
               @Override
               public int compare(BuildSystem left, BuildSystem right)
               {
                  return new Integer(left.priority()).compareTo(right.priority());
               }
            });

            return result;
         }
      });

      buildSystem.setDefaultValue(new Callable<BuildSystem>()
      {
         @Override
         public BuildSystem call() throws Exception
         {
            if (buildSystem.getValueChoices().iterator().hasNext())
            {
               return buildSystem.getValueChoices().iterator().next();
            }
            return null;
         }
      });
   }

   private boolean isProjectTypeBuildable(ProjectType type, BuildSystem buildSystem)
   {
      boolean result = false;
      Iterable<Class<? extends BuildSystemFacet>> requiredFacets = getRequiredBuildSystemFacets(type);
      if (requiredFacets == null || !requiredFacets.iterator().hasNext())
      {
         result = true;
      }
      else
      {
         for (Class<? extends BuildSystemFacet> required : requiredFacets)
         {
            result = false;
            for (Class<? extends BuildSystemFacet> provided : buildSystem.getProvidedFacetTypes())
            {
               if (provided.isAssignableFrom(required))
                  result = true;
            }
            if (!result)
               break;
         }
      }
      return result;
   }

   @SuppressWarnings("unchecked")
   private Iterable<Class<? extends BuildSystemFacet>> getRequiredBuildSystemFacets(ProjectType type)
   {
      Set<Class<? extends BuildSystemFacet>> result = new HashSet<>();
      Iterable<Class<? extends ProjectFacet>> requiredFacets = type.getRequiredFacets();
      if (requiredFacets != null)
      {
         for (Class<? extends ProjectFacet> facetType : requiredFacets)
         {
            if (BuildSystemFacet.class.isAssignableFrom(facetType))
            {
               result.add((Class<? extends BuildSystemFacet>) facetType);
            }
         }
      }
      return result;
   }

{'fraction_non_alphanumeric': 0.10635384334489684, 'fraction_numerical': 0.0007303268212525105, 'mean_word_length': 2.469358669833729, 'pattern_counts': {'":': 0, '<': 80, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2773602', 'n_tokens_mistral': 5930, 'n_tokens_neox': 5759, 'n_words': 1079}