public PsiDirectory[] getSelectedDirectories() {
   final PsiElement[] elements = getSelectedPSIElements();
   if (elements.length == 1) {
     final PsiElement element = elements[0];
     if (element instanceof PsiDirectory) {
       return new PsiDirectory[] {(PsiDirectory) element};
     } else if (element instanceof PsiDirectoryContainer) {
       return ((PsiDirectoryContainer) element).getDirectories();
     } else {
       final PsiFile containingFile = element.getContainingFile();
       if (containingFile != null) {
         final PsiDirectory psiDirectory = containingFile.getContainingDirectory();
         if (psiDirectory != null) {
           return new PsiDirectory[] {psiDirectory};
         }
         final VirtualFile file = containingFile.getVirtualFile();
         if (file instanceof VirtualFileWindow) {
           final VirtualFile delegate = ((VirtualFileWindow) file).getDelegate();
           final PsiFile delegatePsiFile = containingFile.getManager().findFile(delegate);
           if (delegatePsiFile != null && delegatePsiFile.getContainingDirectory() != null) {
             return new PsiDirectory[] {delegatePsiFile.getContainingDirectory()};
           }
         }
         return PsiDirectory.EMPTY_ARRAY;
       }
     }
   } else {
     final DefaultMutableTreeNode selectedNode = getSelectedNode();
     if (selectedNode != null) {
       return getSelectedDirectoriesInAmbiguousCase(selectedNode);
     }
   }
   return PsiDirectory.EMPTY_ARRAY;
 }
 @PsiUtil.AccessLevel
 private static int getEffectiveLevel(
     @NotNull PsiElement element,
     @NotNull PsiFile file,
     @NotNull PsiFile memberFile,
     PsiClass memberClass,
     PsiPackage memberPackage) {
   PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
   if (memberClass != null && PsiTreeUtil.isAncestor(aClass, memberClass, false)
       || aClass != null && PsiTreeUtil.isAncestor(memberClass, aClass, false)) {
     // access from the same file can be via private
     // except when used in annotation:
     // @Ann(value = C.VAL) class C { public static final String VAL = "xx"; }
     PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class);
     if (annotation != null
         && annotation.getParent() instanceof PsiModifierList
         && annotation.getParent().getParent() == aClass) {
       return PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
     }
     return PsiUtil.ACCESS_LEVEL_PRIVATE;
   }
   // if (file == memberFile) {
   //  return PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
   // }
   PsiDirectory directory = file.getContainingDirectory();
   PsiPackage aPackage =
       directory == null ? null : JavaDirectoryService.getInstance().getPackage(directory);
   if (aPackage == memberPackage
       || aPackage != null
           && memberPackage != null
           && Comparing.strEqual(
               aPackage.getQualifiedName(), memberPackage.getQualifiedName())) {
     return PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
   }
   if (aClass != null && memberClass != null && aClass.isInheritor(memberClass, true)) {
     // access from subclass can be via protected, except for constructors
     PsiElement resolved =
         element instanceof PsiReference ? ((PsiReference) element).resolve() : null;
     boolean isConstructor =
         resolved instanceof PsiClass && element.getParent() instanceof PsiNewExpression
             || resolved instanceof PsiMethod && ((PsiMethod) resolved).isConstructor();
     if (!isConstructor) {
       return PsiUtil.ACCESS_LEVEL_PROTECTED;
     }
   }
   return PsiUtil.ACCESS_LEVEL_PUBLIC;
 }
Exemplo n.º 3
0
  @Nullable
  public static String getSourcePositionPackageDisplayName(
      DebugProcessImpl debugProcess, @Nullable SourcePosition position) {
    if (position == null) {
      return null;
    }
    final PsiFile positionFile = position.getFile();
    if (positionFile instanceof JspFile) {
      final PsiDirectory dir = positionFile.getContainingDirectory();
      return dir != null ? dir.getVirtualFile().getPresentableUrl() : null;
    }

    final PsiClass psiClass = getClassAt(position);

    if (psiClass != null) {
      PsiClass toplevel = PsiUtil.getTopLevelClass(psiClass);
      if (toplevel != null) {
        String qName = toplevel.getQualifiedName();
        if (qName != null) {
          int i = qName.lastIndexOf('.');
          return i > 0 ? qName.substring(0, i) : "";
        }
      }
    }

    if (positionFile instanceof PsiClassOwner) {
      String name = ((PsiClassOwner) positionFile).getPackageName();
      if (!StringUtil.isEmpty(name)) {
        return name;
      }
    }

    if (debugProcess != null && debugProcess.isAttached()) {
      List<ReferenceType> allClasses = debugProcess.getPositionManager().getAllClasses(position);
      if (!allClasses.isEmpty()) {
        final String className = allClasses.get(0).name();
        int dotIndex = className.lastIndexOf('.');
        if (dotIndex >= 0) {
          return className.substring(0, dotIndex);
        }
      }
    }
    return "";
  }
  @Nullable
  private RunnerAndConfigurationSettings createConfiguration(final PsiClass aClass) {
    final Project project = aClass.getProject();
    RunnerAndConfigurationSettings settings =
        RunManagerEx.getInstanceEx(project).createConfiguration("", getConfigurationFactory());
    final GroovyScriptRunConfiguration configuration =
        (GroovyScriptRunConfiguration) settings.getConfiguration();
    final PsiFile file = aClass.getContainingFile().getOriginalFile();
    final PsiDirectory dir = file.getContainingDirectory();
    if (dir == null) return null;
    configuration.setWorkDir(dir.getVirtualFile().getPath());
    final VirtualFile vFile = file.getVirtualFile();
    if (vFile == null) return null;
    configuration.setScriptPath(vFile.getPath());
    RunConfigurationModule module = configuration.getConfigurationModule();

    String name = getConfigurationName(aClass, module);
    configuration.setName(name);
    configuration.setModule(JavaExecutionUtil.findModule(aClass));
    return settings;
  }
  @NotNull
  public static SearchScope getClassUseScope(@NotNull PsiClass aClass) {
    if (aClass instanceof PsiAnonymousClass) {
      return new LocalSearchScope(aClass);
    }
    final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(aClass);
    PsiFile file = aClass.getContainingFile();
    if (PsiImplUtil.isInServerPage(file)) return maximalUseScope;
    final PsiClass containingClass = aClass.getContainingClass();
    if (aClass.hasModifierProperty(PsiModifier.PUBLIC)
        || aClass.hasModifierProperty(PsiModifier.PROTECTED)) {
      return containingClass == null ? maximalUseScope : containingClass.getUseScope();
    } else if (aClass.hasModifierProperty(PsiModifier.PRIVATE)
        || aClass instanceof PsiTypeParameter) {
      PsiClass topClass = PsiUtil.getTopLevelClass(aClass);
      return new LocalSearchScope(topClass == null ? aClass.getContainingFile() : topClass);
    } else {
      PsiPackage aPackage = null;
      if (file instanceof PsiJavaFile) {
        aPackage =
            JavaPsiFacade.getInstance(aClass.getProject())
                .findPackage(((PsiJavaFile) file).getPackageName());
      }

      if (aPackage == null) {
        PsiDirectory dir = file.getContainingDirectory();
        if (dir != null) {
          aPackage = JavaDirectoryService.getInstance().getPackage(dir);
        }
      }

      if (aPackage != null) {
        SearchScope scope = PackageScope.packageScope(aPackage, false);
        scope = scope.intersectWith(maximalUseScope);
        return scope;
      }

      return new LocalSearchScope(file);
    }
  }
  static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
    PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
    PsiClass aClass = classReference == null ? null : (PsiClass) classReference.resolve();
    String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
    if (qualifiedName == null) return false;
    if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;

    PsiFile file = aClass.getContainingFile();
    PsiDirectory directory = file.getContainingDirectory();
    PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
    String packageName = classPackage == null ? null : classPackage.getQualifiedName();

    // all Throwable descendants from java.lang are side effects free
    if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
      PsiClass throwableClass =
          JavaPsiFacade.getInstance(aClass.getProject())
              .findClass("java.lang.Throwable", aClass.getResolveScope());
      if (throwableClass != null
          && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
        return true;
      }
    }
    return false;
  }
Exemplo n.º 7
0
  public void performRefactoring(UsageInfo[] usages) {
    final int[] choice = myAllRenames.size() > 1 ? new int[] {-1} : null;
    String message = null;
    try {
      for (Iterator<Map.Entry<PsiElement, String>> iterator = myAllRenames.entrySet().iterator();
          iterator.hasNext(); ) {
        Map.Entry<PsiElement, String> entry = iterator.next();
        if (entry.getKey() instanceof PsiFile) {
          final PsiFile file = (PsiFile) entry.getKey();
          final PsiDirectory containingDirectory = file.getContainingDirectory();
          if (CopyFilesOrDirectoriesHandler.checkFileExist(
              containingDirectory, choice, file, entry.getValue(), "Rename")) {
            iterator.remove();
            continue;
          }
        }
        RenameUtil.checkRename(entry.getKey(), entry.getValue());
      }
    } catch (IncorrectOperationException e) {
      message = e.getMessage();
    }

    if (message != null) {
      CommonRefactoringUtil.showErrorMessage(
          RefactoringBundle.message("rename.title"), message, getHelpID(), myProject);
      return;
    }

    List<Runnable> postRenameCallbacks = new ArrayList<Runnable>();

    final MultiMap<PsiElement, UsageInfo> classified =
        classifyUsages(myAllRenames.keySet(), usages);
    for (final PsiElement element : myAllRenames.keySet()) {
      String newName = myAllRenames.get(element);

      final RefactoringElementListener elementListener =
          getTransaction().getElementListener(element);
      final RenamePsiElementProcessor renamePsiElementProcessor =
          RenamePsiElementProcessor.forElement(element);
      Runnable postRenameCallback =
          renamePsiElementProcessor.getPostRenameCallback(element, newName, elementListener);
      final Collection<UsageInfo> infos = classified.get(element);
      try {
        RenameUtil.doRename(
            element,
            newName,
            infos.toArray(new UsageInfo[infos.size()]),
            myProject,
            elementListener);
      } catch (final IncorrectOperationException e) {
        RenameUtil.showErrorMessage(e, element, myProject);
        return;
      }
      if (postRenameCallback != null) {
        postRenameCallbacks.add(postRenameCallback);
      }
    }

    for (Runnable runnable : postRenameCallbacks) {
      runnable.run();
    }

    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<NonCodeUsageInfo>();
    for (UsageInfo usage : usages) {
      if (usage instanceof NonCodeUsageInfo) {
        nonCodeUsages.add((NonCodeUsageInfo) usage);
      }
    }
    myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
    if (!mySkippedUsages.isEmpty()) {
      if (!ApplicationManager.getApplication().isUnitTestMode()
          && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  public void run() {
                    final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myProject);
                    if (ideFrame != null) {

                      StatusBarEx statusBar = (StatusBarEx) ideFrame.getStatusBar();
                      HyperlinkListener listener =
                          new HyperlinkListener() {
                            public void hyperlinkUpdate(HyperlinkEvent e) {
                              if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return;
                              Messages.showMessageDialog(
                                  "<html>"
                                      + StringUtil.join(
                                          mySkippedUsages,
                                          new Function<UnresolvableCollisionUsageInfo, String>() {
                                            public String fun(
                                                UnresolvableCollisionUsageInfo
                                                    unresolvableCollisionUsageInfo) {
                                              return unresolvableCollisionUsageInfo
                                                  .getDescription();
                                            }
                                          },
                                          "<br>")
                                      + "</html>",
                                  "Don't panic! They are safe to skip",
                                  null);
                            }
                          };
                      statusBar.notifyProgressByBalloon(
                          MessageType.WARNING,
                          "<html><body>Unable to rename certain usages. <a href=\"\">Browse</a></body></html>",
                          null,
                          listener);
                    }
                  }
                },
                ModalityState.NON_MODAL);
      }
    }
  }
  public void invoke(
      @NotNull final Project project,
      final Editor editor,
      final PsiFile file,
      DataContext dataContext) {
    myIncludingFile = file;
    if (!editor.getSelectionModel().hasSelection()) {
      String message =
          RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("no.selection"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }
    final int start = editor.getSelectionModel().getSelectionStart();
    final int end = editor.getSelectionModel().getSelectionEnd();

    final Pair<T, T> children = findPairToExtract(start, end);
    if (children == null) {
      String message =
          RefactoringBundle.getCannotRefactorMessage(
              RefactoringBundle.message("selection.does.not.form.a.fragment.for.extraction"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    if (!verifyChildRange(children.getFirst(), children.getSecond())) {
      String message =
          RefactoringBundle.getCannotRefactorMessage(
              RefactoringBundle.message("cannot.extract.selected.elements.into.include.file"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    final FileType fileType = getFileType(getLanguageForExtract(children.getFirst()));
    if (!(fileType instanceof LanguageFileType)) {
      String message =
          RefactoringBundle.message(
              "the.language.for.selected.elements.has.no.associated.file.type");
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return;

    ExtractIncludeDialog dialog =
        createDialog(file.getContainingDirectory(), getExtractExtension(fileType, children.first));
    dialog.show();
    if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
      final PsiDirectory targetDirectory = dialog.getTargetDirectory();
      LOG.assertTrue(targetDirectory != null);
      final String targetfileName = dialog.getTargetFileName();
      CommandProcessor.getInstance()
          .executeCommand(
              project,
              new Runnable() {
                public void run() {
                  ApplicationManager.getApplication()
                      .runWriteAction(
                          new Runnable() {
                            public void run() {
                              try {
                                final List<IncludeDuplicate<T>> duplicates =
                                    new ArrayList<IncludeDuplicate<T>>();
                                final T first = children.getFirst();
                                final T second = children.getSecond();
                                PsiEquivalenceUtil.findChildRangeDuplicates(
                                    first,
                                    second,
                                    file,
                                    new PairConsumer<PsiElement, PsiElement>() {
                                      public void consume(
                                          final PsiElement start, final PsiElement end) {
                                        duplicates.add(new IncludeDuplicate<T>((T) start, (T) end));
                                      }
                                    });
                                final String includePath =
                                    processPrimaryFragment(
                                        first, second, targetDirectory, targetfileName, file);
                                editor
                                    .getCaretModel()
                                    .moveToOffset(first.getTextRange().getStartOffset());

                                ApplicationManager.getApplication()
                                    .invokeLater(
                                        new Runnable() {
                                          public void run() {
                                            replaceDuplicates(
                                                includePath, duplicates, editor, project);
                                          }
                                        });
                              } catch (IncorrectOperationException e) {
                                CommonRefactoringUtil.showErrorMessage(
                                    getRefactoringName(), e.getMessage(), null, project);
                              }

                              editor.getSelectionModel().removeSelection();
                            }
                          });
                }
              },
              getRefactoringName(),
              null);
    }
  }
  private PsiClass buildClass() {
    if (existingClass != null) {
      return existingClass;
    }
    final ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder();
    beanClassBuilder.setVisibility(myCreateInnerClass ? PsiModifier.PRIVATE : PsiModifier.PUBLIC);
    beanClassBuilder.setProject(myProject);
    beanClassBuilder.setTypeArguments(typeParams);
    beanClassBuilder.setClassName(className);
    beanClassBuilder.setPackageName(packageName);
    for (ParameterChunk parameterChunk : parameters) {
      final VariableData parameter = parameterChunk.parameter;
      final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable);
      beanClassBuilder.addField(
          (PsiParameter) parameter.variable, parameter.name, parameter.type, setterRequired);
    }
    final String classString = beanClassBuilder.buildBeanClass();

    try {
      final PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject());
      final PsiJavaFile newFile =
          (PsiJavaFile)
              factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString);
      if (myCreateInnerClass) {
        final PsiClass containingClass = method.getContainingClass();
        final PsiClass[] classes = newFile.getClasses();
        assert classes.length > 0 : classString;
        final PsiClass innerClass = (PsiClass) containingClass.add(classes[0]);
        PsiUtil.setModifierProperty(innerClass, PsiModifier.STATIC, true);
        return (PsiClass)
            JavaCodeStyleManager.getInstance(newFile.getProject())
                .shortenClassReferences(innerClass);
      } else {
        final PsiFile containingFile = method.getContainingFile();
        final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
        final PsiDirectory directory;
        if (myMoveDestination != null) {
          directory = myMoveDestination.getTargetDirectory(containingDirectory);
        } else {
          final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
          directory =
              PackageUtil.findOrCreateDirectoryForPackage(
                  module, packageName, containingDirectory, true, true);
        }

        if (directory != null) {

          final CodeStyleManager codeStyleManager =
              CodeStyleManager.getInstance(method.getManager().getProject());
          final PsiElement shortenedFile =
              JavaCodeStyleManager.getInstance(newFile.getProject())
                  .shortenClassReferences(newFile);
          final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile);
          return ((PsiJavaFile) directory.add(reformattedFile)).getClasses()[0];
        }
      }
    } catch (IncorrectOperationException e) {
      logger.info(e);
    }
    return null;
  }
    private void checkMember(@NotNull final PsiMember member) {
      if (member.hasModifierProperty(PsiModifier.PRIVATE)
          || member.hasModifierProperty(PsiModifier.NATIVE)) return;
      if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical())
        return;

      if (member instanceof PsiMethod) {
        PsiMethod method = (PsiMethod) member;
        if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) {
          log(member.getName() + " overrides");
          return; // overrides
        }
        if (MethodUtils.isOverridden(method)) {
          log(member.getName() + " overridden");
          return;
        }
      }
      if (member instanceof PsiEnumConstant) return;
      if (member instanceof PsiClass
          && (member instanceof PsiAnonymousClass
              || member instanceof PsiTypeParameter
              || member instanceof PsiSyntheticClass
              || PsiUtil.isLocalClass((PsiClass) member))) {
        return;
      }
      final PsiClass memberClass = member.getContainingClass();
      if (memberClass != null
          && (memberClass.isInterface()
              || memberClass.isEnum()
              || memberClass.isAnnotationType()
              || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) {
        return;
      }
      final PsiFile memberFile = member.getContainingFile();
      Project project = memberFile.getProject();

      if (myDeadCodeInspection.isEntryPoint(member)) {
        log(member.getName() + " is entry point");
        return;
      }

      PsiModifierList memberModifierList = member.getModifierList();
      if (memberModifierList == null) return;
      final int currentLevel = PsiUtil.getAccessLevel(memberModifierList);
      final AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE);
      final AtomicBoolean foundUsage = new AtomicBoolean();
      PsiDirectory memberDirectory = memberFile.getContainingDirectory();
      final PsiPackage memberPackage =
          memberDirectory == null
              ? null
              : JavaDirectoryService.getInstance().getPackage(memberDirectory);
      log(member.getName() + ": checking effective level for " + member);
      boolean result =
          UnusedSymbolUtil.processUsages(
              project,
              memberFile,
              member,
              new EmptyProgressIndicator(),
              null,
              new Processor<UsageInfo>() {
                @Override
                public boolean process(UsageInfo info) {
                  foundUsage.set(true);
                  PsiFile psiFile = info.getFile();
                  if (psiFile == null) return true;
                  if (!(psiFile instanceof PsiJavaFile)) {
                    log("     refd from " + psiFile.getName() + "; set to public");
                    maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
                    if (memberClass != null) {
                      childMembersAreUsedOutsideMyPackage.add(memberClass);
                    }
                    return false; // referenced from XML, has to be public
                  }
                  // int offset = info.getNavigationOffset();
                  // if (offset == -1) return true;
                  PsiElement element = info.getElement();
                  if (element == null) return true;
                  @PsiUtil.AccessLevel
                  int level =
                      getEffectiveLevel(element, psiFile, memberFile, memberClass, memberPackage);
                  log(
                      "    ref in file "
                          + psiFile.getName()
                          + "; level = "
                          + PsiUtil.getAccessModifier(level)
                          + "; ("
                          + element
                          + ")");
                  while (true) {
                    int oldLevel = maxLevel.get();
                    if (level <= oldLevel || maxLevel.compareAndSet(oldLevel, level)) break;
                  }
                  if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
                    childMembersAreUsedOutsideMyPackage.add(memberClass);
                  }

                  return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
                }
              });

      if (!foundUsage.get()) {
        log(member.getName() + " unused; ignore");
        return; // do not propose private for unused method
      }
      int max = maxLevel.get();
      if (max == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) {
        max = PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
      }

      log(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(max) + "'");

      if (max < currentLevel) {
        if (max == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
            && member instanceof PsiClass
            && childMembersAreUsedOutsideMyPackage.contains(member)) {
          log(member.getName() + "  children used outside my package; ignore");
          return; // e.g. some public method is used outside my package (without importing class)
        }
        PsiElement toHighlight =
            currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
                ? ((PsiNameIdentifierOwner) member).getNameIdentifier()
                : ContainerUtil.find(
                    memberModifierList.getChildren(),
                    new Condition<PsiElement>() {
                      @Override
                      public boolean value(PsiElement element) {
                        return element instanceof PsiKeyword
                            && element.getText().equals(PsiUtil.getAccessModifier(currentLevel));
                      }
                    });
        assert toHighlight != null
            : member
                + " ; "
                + ((PsiNameIdentifierOwner) member).getNameIdentifier()
                + "; "
                + memberModifierList.getText();
        myHolder.registerProblem(
            toHighlight,
            "Access can be " + PsiUtil.getAccessModifier(max),
            new ChangeModifierFix(PsiUtil.getAccessModifier(max)));
      }
    }
  @NotNull
  protected PsiElement[] invokeDialog(final Project project, final PsiDirectory directory) {
    final FileChooserDescriptor descriptor =
        FileChooserDescriptorFactory.createSingleFolderDescriptor();
    descriptor.setRoots(project.getBaseDir());
    PsiDirectory currentDir = currentFile.getContainingDirectory();
    PsiDirectory includeDir = currentDir.findSubdirectory("Includes");
    VirtualFile selectDir = directory.getVirtualFile();
    if (includeDir == null) {
      PsiDirectory parentDir = currentDir.getParentDirectory();
      if (parentDir != null) {
        includeDir = parentDir.findSubdirectory("Includes");
      }
    }
    if (includeDir != null) selectDir = includeDir.getVirtualFile();

    final VirtualFile myFolder = FileChooser.chooseFile(descriptor, project, selectDir);
    if (myFolder != null) {
      PsiDirectory myDirectory = PsiManager.getInstance(project).findDirectory(myFolder);
      final MyInputValidator validator = new MyInputValidator(project, myDirectory);
      final String fileName =
          Messages.showInputDialog(
              project,
              getDialogPrompt(),
              getDialogTitle(),
              Messages.getQuestionIcon(),
              "",
              validator);

      final PsiElement[] elements = validator.getCreatedElements();
      if (elements.length > 0) {
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  @Override
                  public void run() {
                    ApplicationManager.getApplication()
                        .runWriteAction(
                            new Runnable() {
                              @Override
                              public void run() {
                                try {
                                  CodeStyleManager codeStyleManager =
                                      CodeStyleManager.getInstance(project);
                                  CaretModel caretModel = editor.getCaretModel();
                                  int caretOffset = selectonModel.getSelectionStart();
                                  EditorModificationUtil.deleteSelectedText(editor);
                                  PsiDocumentManager psiDocumentManager =
                                      PsiDocumentManager.getInstance(project);
                                  caretModel.moveToOffset(caretOffset);
                                  EditorModificationUtil.insertStringAtCaret(
                                      editor, "<% include " + fileName + " %>", true, false);
                                  PsiFile createdFile = (PsiFile) elements[0];
                                  codeStyleManager.reformat(createdFile);
                                  psiDocumentManager.commitDocument(
                                      psiDocumentManager.getDocument(currentFile));
                                  FileEditorManager.getInstance(project)
                                      .openFile(currentFile.getVirtualFile(), true);
                                  codeStyleManager.adjustLineIndent(currentFile, caretOffset);
                                  psiDocumentManager.commitDocument(
                                      psiDocumentManager.getDocument(currentFile));
                                } catch (Exception e) {
                                  e.printStackTrace(); // To change body of catch statement use
                                  // File | Settings | File Templates.
                                }
                              }
                            });
                  }
                });
      }
      return elements;
    }
    return PsiElement.EMPTY_ARRAY;
  }
  private PsiClass buildClass() {
    final PsiManager manager = sourceClass.getManager();
    final Project project = sourceClass.getProject();
    final ExtractedClassBuilder extractedClassBuilder = new ExtractedClassBuilder();
    extractedClassBuilder.setProject(myProject);
    extractedClassBuilder.setClassName(newClassName);
    extractedClassBuilder.setPackageName(newPackageName);
    extractedClassBuilder.setOriginalClassName(sourceClass.getQualifiedName());
    extractedClassBuilder.setRequiresBackPointer(requiresBackpointer);
    extractedClassBuilder.setExtractAsEnum(enumConstants);
    for (PsiField field : fields) {
      extractedClassBuilder.addField(field);
    }
    for (PsiMethod method : methods) {
      extractedClassBuilder.addMethod(method);
    }
    for (PsiClass innerClass : innerClasses) {
      extractedClassBuilder.addInnerClass(
          innerClass, innerClassesToMakePublic.contains(innerClass));
    }
    extractedClassBuilder.setTypeArguments(typeParams);
    final List<PsiClass> interfaces = calculateInterfacesSupported();
    extractedClassBuilder.setInterfaces(interfaces);

    if (myGenerateAccessors) {
      final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4ExtractedClass();
      sourceClass.accept(visitor);
      extractedClassBuilder.setFieldsNeedingGetters(visitor.getFieldsNeedingGetter());
      extractedClassBuilder.setFieldsNeedingSetters(visitor.getFieldsNeedingSetter());
    }

    final String classString = extractedClassBuilder.buildBeanClass();
    if (extractInnerClass) {
      final PsiFileFactory factory = PsiFileFactory.getInstance(project);
      final PsiJavaFile newFile =
          (PsiJavaFile)
              factory.createFileFromText(
                  newClassName + ".java", JavaFileType.INSTANCE, classString);
      final PsiClass psiClass = newFile.getClasses()[0];
      if (!psiClass.isEnum()) {
        final PsiModifierList modifierList = psiClass.getModifierList();
        assert modifierList != null;
        modifierList.setModifierProperty(PsiModifier.STATIC, true);
      }
      final PsiElement addedClass = sourceClass.add(psiClass);
      return (PsiClass)
          CodeStyleManager.getInstance(manager)
              .reformat(
                  JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedClass));
    }

    try {
      final PsiFile containingFile = sourceClass.getContainingFile();
      final PsiDirectory directory;
      final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
      if (myMoveDestination != null) {
        directory = myMoveDestination.getTargetDirectory(containingDirectory);
      } else {
        final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
        assert module != null;
        directory =
            PackageUtil.findOrCreateDirectoryForPackage(
                module, newPackageName, containingDirectory, false, true);
      }
      if (directory != null) {
        final PsiFileFactory factory = PsiFileFactory.getInstance(project);
        final PsiFile newFile =
            factory.createFileFromText(newClassName + ".java", JavaFileType.INSTANCE, classString);
        final PsiElement addedFile = directory.add(newFile);
        final CodeStyleManager codeStyleManager =
            CodeStyleManager.getInstance(manager.getProject());
        final PsiElement shortenedFile =
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedFile);
        return ((PsiJavaFile) codeStyleManager.reformat(shortenedFile)).getClasses()[0];
      } else {
        return null;
      }
    } catch (IncorrectOperationException e) {
      return null;
    }
  }
 public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) {
   FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass");
   final HashMap<PsiFile, String> relativePathsMap = new HashMap<PsiFile, String>();
   final Map<PsiFile, PsiClass[]> classes =
       convertToTopLevelClasses(elements, false, "", relativePathsMap);
   assert classes != null;
   if (defaultTargetDirectory == null) {
     final PsiFile psiFile = classes.keySet().iterator().next();
     defaultTargetDirectory = psiFile.getContainingDirectory();
     LOG.assertTrue(defaultTargetDirectory != null, psiFile);
   } else {
     Project project = defaultTargetDirectory.getProject();
     VirtualFile sourceRootForFile =
         ProjectRootManager.getInstance(project)
             .getFileIndex()
             .getSourceRootForFile(defaultTargetDirectory.getVirtualFile());
     if (sourceRootForFile == null) {
       final List<PsiElement> files = new ArrayList<PsiElement>();
       for (int i = 0, elementsLength = elements.length; i < elementsLength; i++) {
         PsiFile containingFile = elements[i].getContainingFile();
         if (containingFile != null) {
           files.add(containingFile);
         } else if (elements[i] instanceof PsiDirectory) {
           files.add(elements[i]);
         }
       }
       CopyFilesOrDirectoriesHandler.copyAsFiles(
           files.toArray(new PsiElement[files.size()]), defaultTargetDirectory, project);
       return;
     }
   }
   Project project = defaultTargetDirectory.getProject();
   Object targetDirectory = null;
   String className = null;
   boolean openInEditor = true;
   if (copyOneClass(classes)) {
     final String commonPath =
         ArrayUtil.find(elements, classes.values().iterator().next()) == -1
             ? normalizeRelativeMap(relativePathsMap)
             : null;
     CopyClassDialog dialog =
         new CopyClassDialog(
             classes.values().iterator().next()[0], defaultTargetDirectory, project, false) {
           @Override
           protected String getQualifiedName() {
             if (commonPath != null && !commonPath.isEmpty()) {
               return StringUtil.getQualifiedName(
                   super.getQualifiedName(), commonPath.replaceAll("/", "."));
             }
             return super.getQualifiedName();
           }
         };
     dialog.setTitle(RefactoringBundle.message("copy.handler.copy.class"));
     dialog.show();
     if (dialog.isOK()) {
       openInEditor = dialog.openInEditor();
       targetDirectory = dialog.getTargetDirectory();
       className = dialog.getClassName();
       if (className == null || className.length() == 0) return;
     }
   } else {
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       targetDirectory = defaultTargetDirectory;
     } else {
       defaultTargetDirectory =
           CopyFilesOrDirectoriesHandler.resolveDirectory(defaultTargetDirectory);
       if (defaultTargetDirectory == null) return;
       PsiElement[] files = PsiUtilCore.toPsiFileArray(classes.keySet());
       if (classes.keySet().size() == 1) {
         // do not choose a new name for a file when multiple classes exist in one file
         final PsiClass[] psiClasses = classes.values().iterator().next();
         if (psiClasses != null) {
           files = psiClasses;
         }
       }
       final CopyFilesOrDirectoriesDialog dialog =
           new CopyFilesOrDirectoriesDialog(files, defaultTargetDirectory, project, false);
       dialog.show();
       if (dialog.isOK()) {
         targetDirectory = dialog.getTargetDirectory();
         className = dialog.getNewName();
         openInEditor = dialog.openInEditor();
       }
     }
   }
   if (targetDirectory != null) {
     copyClassesImpl(
         className,
         project,
         classes,
         relativePathsMap,
         targetDirectory,
         defaultTargetDirectory,
         RefactoringBundle.message("copy.handler.copy.class"),
         false,
         openInEditor);
   }
 }