2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 package com
.intellij
.psi
.impl
.file
;
22 import com
.intellij
.ide
.fileTemplates
.FileTemplate
;
23 import com
.intellij
.ide
.fileTemplates
.FileTemplateManager
;
24 import com
.intellij
.ide
.fileTemplates
.FileTemplateUtil
;
25 import com
.intellij
.ide
.fileTemplates
.JavaTemplateUtil
;
26 import com
.intellij
.openapi
.diagnostic
.Logger
;
27 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
28 import com
.intellij
.openapi
.module
.LanguageLevelUtil
;
29 import com
.intellij
.openapi
.module
.Module
;
30 import com
.intellij
.openapi
.project
.Project
;
31 import com
.intellij
.openapi
.roots
.LanguageLevelProjectExtension
;
32 import com
.intellij
.openapi
.roots
.ProjectFileIndex
;
33 import com
.intellij
.openapi
.roots
.ProjectRootManager
;
34 import com
.intellij
.openapi
.util
.Key
;
35 import com
.intellij
.openapi
.util
.text
.StringUtil
;
36 import com
.intellij
.openapi
.vfs
.VirtualFile
;
37 import com
.intellij
.pom
.java
.LanguageLevel
;
38 import com
.intellij
.psi
.*;
39 import com
.intellij
.psi
.util
.PsiUtil
;
40 import com
.intellij
.util
.IncorrectOperationException
;
41 import org
.jetbrains
.annotations
.NotNull
;
43 import java
.util
.ArrayList
;
44 import java
.util
.Arrays
;
45 import java
.util
.Properties
;
47 public class JavaDirectoryServiceImpl
extends JavaDirectoryService
{
48 private static final Logger LOG
= Logger
.getInstance("#com.intellij.psi.impl.file.JavaDirectoryServiceImpl");
50 public PsiPackage
getPackage(@NotNull PsiDirectory dir
) {
51 ProjectFileIndex projectFileIndex
= ProjectRootManager
.getInstance(dir
.getProject()).getFileIndex();
52 String packageName
= projectFileIndex
.getPackageNameByDirectory(dir
.getVirtualFile());
53 if (packageName
== null) return null;
54 return JavaPsiFacade
.getInstance(dir
.getProject()).findPackage(packageName
);
58 public PsiClass
[] getClasses(@NotNull PsiDirectory dir
) {
59 LOG
.assertTrue(dir
.isValid());
61 ArrayList
<PsiClass
> classes
= new ArrayList
<PsiClass
>();
62 for (PsiFile file
: dir
.getFiles()) {
63 if (file
instanceof PsiClassOwner
) {
64 classes
.addAll(Arrays
.asList(((PsiClassOwner
)file
).getClasses()));
67 return classes
.toArray(new PsiClass
[classes
.size()]);
71 public PsiClass
createClass(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
72 return createClassFromTemplate(dir
, name
, JavaTemplateUtil
.INTERNAL_CLASS_TEMPLATE_NAME
);
76 public PsiClass
createClass(@NotNull PsiDirectory dir
, @NotNull String name
, @NotNull String templateName
) throws IncorrectOperationException
{
77 return createClassFromTemplate(dir
, name
, templateName
);
81 public PsiClass
createInterface(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
82 String templateName
= JavaTemplateUtil
.INTERNAL_INTERFACE_TEMPLATE_NAME
;
83 PsiClass someClass
= createClassFromTemplate(dir
, name
, templateName
);
84 if (!someClass
.isInterface()) {
85 throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName
));
91 public PsiClass
createEnum(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
92 String templateName
= JavaTemplateUtil
.INTERNAL_ENUM_TEMPLATE_NAME
;
93 PsiClass someClass
= createClassFromTemplate(dir
, name
, templateName
);
94 if (!someClass
.isEnum()) {
95 throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName
));
101 public PsiClass
createAnnotationType(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
102 String templateName
= JavaTemplateUtil
.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME
;
103 PsiClass someClass
= createClassFromTemplate(dir
, name
, templateName
);
104 if (!someClass
.isAnnotationType()) {
105 throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName
));
110 private static PsiClass
createClassFromTemplate(@NotNull PsiDirectory dir
, String name
, String templateName
) throws IncorrectOperationException
{
111 checkCreateClassOrInterface(dir
, name
);
113 FileTemplate template
= FileTemplateManager
.getInstance().getInternalTemplate(templateName
);
115 Properties defaultProperties
= FileTemplateManager
.getInstance().getDefaultProperties();
116 Properties properties
= new Properties(defaultProperties
);
117 properties
.setProperty(FileTemplate
.ATTRIBUTE_NAME
, name
);
119 String ext
= StdFileTypes
.JAVA
.getDefaultExtension();
120 String fileName
= name
+ "." + ext
;
124 element
= FileTemplateUtil
.createFromTemplate(template
, fileName
, properties
, dir
);
126 catch (IncorrectOperationException e
) {
129 catch (Exception e
) {
134 final PsiJavaFile file
= (PsiJavaFile
)element
.getContainingFile();
135 PsiClass
[] classes
= file
.getClasses();
136 if (classes
.length
!= 1 || !name
.equals(classes
[0].getName())) {
137 throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName
));
139 return file
.getClasses()[0];
142 private static String
getIncorrectTemplateMessage(String templateName
) {
143 return PsiBundle
.message("psi.error.incorroect.class.template.message",
144 FileTemplateManager
.getInstance().internalTemplateToSubject(templateName
), templateName
);
147 public void checkCreateClass(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
148 checkCreateClassOrInterface(dir
, name
);
151 public void checkCreateInterface(@NotNull PsiDirectory dir
, @NotNull String name
) throws IncorrectOperationException
{
152 checkCreateClassOrInterface(dir
, name
);
158 public static void checkCreateClassOrInterface(@NotNull PsiDirectory directory
, String name
) throws IncorrectOperationException
{
159 PsiUtil
.checkIsIdentifier(directory
.getManager(), name
);
161 String fileName
= name
+ "." + StdFileTypes
.JAVA
.getDefaultExtension();
162 directory
.checkCreateFile(fileName
);
164 PsiNameHelper helper
= JavaPsiFacade
.getInstance(directory
.getProject()).getNameHelper();
165 PsiPackage aPackage
= JavaDirectoryService
.getInstance().getPackage(directory
);
166 String qualifiedName
= aPackage
== null ?
null : aPackage
.getQualifiedName();
167 if (!StringUtil
.isEmpty(qualifiedName
) && !helper
.isQualifiedName(qualifiedName
)) {
168 throw new IncorrectOperationException("Cannot create class in invalid package: '"+qualifiedName
+"'");
172 public boolean isSourceRoot(@NotNull PsiDirectory dir
) {
173 final VirtualFile file
= dir
.getVirtualFile();
174 final VirtualFile sourceRoot
= ProjectRootManager
.getInstance(dir
.getProject()).getFileIndex().getSourceRootForFile(file
);
175 return file
.equals(sourceRoot
);
178 private static final Key
<LanguageLevel
> LANG_LEVEL_IN_DIRECTORY
= new Key
<LanguageLevel
>("LANG_LEVEL_IN_DIRECTORY");
179 public LanguageLevel
getLanguageLevel(@NotNull PsiDirectory dir
) {
180 synchronized (PsiLock
.LOCK
) {
181 LanguageLevel level
= dir
.getUserData(LANG_LEVEL_IN_DIRECTORY
);
183 level
= getLanguageLevelInner(dir
);
184 dir
.putUserData(LANG_LEVEL_IN_DIRECTORY
, level
);
190 private static LanguageLevel
getLanguageLevelInner(@NotNull PsiDirectory dir
) {
191 final VirtualFile virtualFile
= dir
.getVirtualFile();
192 final Project project
= dir
.getProject();
193 final Module module
= ProjectRootManager
.getInstance(project
).getFileIndex().getModuleForFile(virtualFile
);
194 if (module
!= null) {
195 return LanguageLevelUtil
.getEffectiveLanguageLevel(module
);
198 return LanguageLevelProjectExtension
.getInstance(project
).getLanguageLevel();