9d874e11c9d45e275f23d73aa8961d9b2a670695
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / actions / CreateTemplateInPackageAction.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.ide.actions;
18
19 import com.intellij.ide.IdeView;
20 import com.intellij.openapi.actionSystem.DataContext;
21 import com.intellij.openapi.actionSystem.LangDataKeys;
22 import com.intellij.openapi.actionSystem.PlatformDataKeys;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.roots.ProjectFileIndex;
25 import com.intellij.openapi.roots.ProjectRootManager;
26 import com.intellij.openapi.util.text.StringUtil;
27 import com.intellij.psi.PsiDirectory;
28 import com.intellij.psi.PsiElement;
29 import com.intellij.util.IncorrectOperationException;
30 import org.jetbrains.annotations.NotNull;
31 import org.jetbrains.annotations.Nullable;
32
33 import javax.swing.*;
34
35 /**
36  * @author peter
37  */
38 public abstract class CreateTemplateInPackageAction<T extends PsiElement> extends CreateFromTemplateAction<T> {
39   private final boolean myInSourceOnly;
40
41   protected CreateTemplateInPackageAction(String text, String description, Icon icon, boolean inSourceOnly) {
42     super(text, description, icon);
43     myInSourceOnly = inSourceOnly;
44   }
45
46   @Override
47   @Nullable
48   protected T createFile(String name, String templateName, PsiDirectory dir) {
49     return checkOrCreate(name, dir, templateName);
50   }
51
52   @Nullable
53   protected abstract PsiElement getNavigationElement(@NotNull T createdElement);
54
55   @Override
56   protected boolean isAvailable(final DataContext dataContext) {
57     final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
58     final IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext);
59     if (project == null || view == null || view.getDirectories().length == 0) {
60       return false;
61     }
62
63     if (!myInSourceOnly) {
64       return true;
65     }
66
67     ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
68     for (PsiDirectory dir : view.getDirectories()) {
69       if (projectFileIndex.isInSourceContent(dir.getVirtualFile()) && checkPackageExists(dir)) {
70         return true;
71       }
72     }
73
74     return false;
75   }
76
77   protected abstract boolean checkPackageExists(PsiDirectory directory);
78
79   @Nullable
80   private T checkOrCreate(String newName, PsiDirectory directory, String templateName) throws IncorrectOperationException {
81     PsiDirectory dir = directory;
82     String className = newName;
83
84     final String extension = StringUtil.getShortName(templateName);
85     if (StringUtil.isNotEmpty(extension)) {
86       className = StringUtil.trimEnd(className, "." + extension);
87     }
88
89     if (className.contains(".")) {
90       String[] names = className.split("\\.");
91
92       for (int i = 0; i < names.length - 1; i++) {
93         String name = names[i];
94         PsiDirectory subDir = dir.findSubdirectory(name);
95
96         if (subDir == null) {
97           subDir = dir.createSubdirectory(name);
98         }
99
100         dir = subDir;
101       }
102
103       className = names[names.length - 1];
104     }
105
106     return doCreate(dir, className, templateName);
107   }
108
109   @Nullable
110   protected abstract T doCreate(final PsiDirectory dir, final String className, String templateName) throws IncorrectOperationException;
111
112 }