blob: 67db267ea30aa4a30505e2588e4b81eb6ce162a9 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.devkit.inspections.quickfix;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.icons.AllIcons;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.components.JBList;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.devkit.DevKitBundle;
import org.jetbrains.idea.devkit.inspections.DescriptionCheckerUtil;
import org.jetbrains.idea.devkit.inspections.DescriptionType;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import org.jetbrains.jps.model.java.JavaResourceRootType;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
@NonNls
private static final String TEMPLATE_NAME = "InspectionDescription.html";
private final String myFilename;
private final Module myModule;
private final DescriptionType myDescriptionType;
public CreateHtmlDescriptionFix(String filename, Module module, DescriptionType descriptionType) {
myModule = module;
myDescriptionType = descriptionType;
myFilename = getNormalizedFileName(filename);
}
private boolean isFixedDescriptionFilename() {
return myDescriptionType.isFixedDescriptionFilename();
}
private static List<VirtualFile> getPotentialRoots(Module module, PsiDirectory[] dirs) {
if (dirs.length != 0) {
final List<VirtualFile> result = new ArrayList<VirtualFile>();
for (PsiDirectory dir : dirs) {
final PsiDirectory parent = dir.getParentDirectory();
if (parent != null) result.add(parent.getVirtualFile());
}
return result;
}
else {
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
List<VirtualFile> resourceRoots = rootManager.getSourceRoots(JavaResourceRootType.RESOURCE);
if (!resourceRoots.isEmpty()) {
return resourceRoots;
}
return rootManager.getSourceRoots(JavaModuleSourceRootTypes.SOURCES);
}
}
private String getNormalizedFileName(String filename) {
return myDescriptionType.isFixedDescriptionFilename() ? filename : filename + ".html";
}
@NotNull
public String getName() {
return DevKitBundle.message("create.description.file");
}
@NotNull
public String getFamilyName() {
return "DevKit";
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiDirectory[] dirs = getDirectories();
final List<VirtualFile> virtualFiles = getPotentialRoots(myModule, dirs);
final VirtualFile[] roots = prepare(VfsUtilCore.toVirtualFileArray(virtualFiles));
if (roots.length == 1) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
createDescription(roots[0]);
}
});
}
else {
List<String> options = new ArrayList<String>();
for (VirtualFile file : roots) {
String path = getPath(file);
options.add(path);
}
final JBList files = new JBList(ArrayUtil.toStringArray(options));
files.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JBPopup popup = JBPopupFactory.getInstance()
.createListPopupBuilder(files)
.setTitle(DevKitBundle.message("select.target.location.of.description", myFilename))
.setItemChoosenCallback(new Runnable() {
public void run() {
final int index = files.getSelectedIndex();
if (0 <= index && index < roots.length) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
createDescription(roots[index]);
}
});
}
}
}).createPopup();
final Editor editor = FileEditorManager.getInstance(myModule.getProject()).getSelectedTextEditor();
if (editor == null) return;
popup.showInBestPositionFor(editor);
}
}
private String getPath(VirtualFile file) {
String path = file.getPresentableUrl() + File.separator + getDescriptionFolderName() + File.separator + myFilename;
if (isFixedDescriptionFilename()) {
path += File.separator + "description.html";
}
return path;
}
private PsiDirectory[] getDirectories() {
return DescriptionCheckerUtil.getDescriptionsDirs(myModule, myDescriptionType);
}
private void createDescription(VirtualFile root) {
if (!root.isDirectory()) return;
final PsiManager psiManager = PsiManager.getInstance(myModule.getProject());
final PsiDirectory psiRoot = psiManager.findDirectory(root);
PsiDirectory descrRoot = null;
if (psiRoot == null) return;
for (PsiDirectory dir : psiRoot.getSubdirectories()) {
if (getDescriptionFolderName().equals(dir.getName())) {
descrRoot = dir;
break;
}
}
try {
descrRoot = descrRoot == null ? psiRoot.createSubdirectory(getDescriptionFolderName()) : descrRoot;
if (isFixedDescriptionFilename()) {
PsiDirectory dir = descrRoot.findSubdirectory(myFilename);
if (dir == null) {
descrRoot = descrRoot.createSubdirectory(myFilename);
}
}
final FileTemplate descrTemplate = FileTemplateManager.getInstance().getJ2eeTemplate(TEMPLATE_NAME);
final PsiElement template =
FileTemplateUtil.createFromTemplate(descrTemplate, getNewFileName(), null, descrRoot);
if (template instanceof PsiFile) {
final VirtualFile file = ((PsiFile)template).getVirtualFile();
if (file != null) {
FileEditorManager.getInstance(myModule.getProject()).openFile(file, true);
}
}
}
catch (Exception e) {//
}
}
private String getNewFileName() {
return isFixedDescriptionFilename() ? "description.html" : myFilename;
}
public Icon getIcon(int flags) {
return new LayeredIcon(AllIcons.FileTypes.Html, AllIcons.Actions.New);
}
private VirtualFile[] prepare(VirtualFile[] roots) {
List<VirtualFile> found = new ArrayList<VirtualFile>();
for (VirtualFile root : roots) {
if (containsDescriptionDir(root)) {
found.add(root);
}
}
return found.size() > 0 ? VfsUtilCore.toVirtualFileArray(found) : roots;
}
private boolean containsDescriptionDir(VirtualFile root) {
if (!root.isDirectory()) return false;
for (VirtualFile file : root.getChildren()) {
if (file.isDirectory() && getDescriptionFolderName().equals(file.getName())) {
return true;
}
}
return false;
}
private String getDescriptionFolderName() {
return myDescriptionType.getDescriptionFolder();
}
}