update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / file / JavaDirectoryServiceImpl.java
blob129c20e3be7c6c5bc0330649bcbb55fe2f7f0365
1 /*
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.
18 * @author max
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);
57 @NotNull
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()]);
70 @NotNull
71 public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
72 return createClassFromTemplate(dir, name, JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME);
75 @NotNull
76 public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name, @NotNull String templateName) throws IncorrectOperationException {
77 return createClassFromTemplate(dir, name, templateName);
80 @NotNull
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));
87 return someClass;
90 @NotNull
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));
97 return someClass;
100 @NotNull
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));
107 return someClass;
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;
122 PsiElement element;
123 try {
124 element = FileTemplateUtil.createFromTemplate(template, fileName, properties, dir);
126 catch (IncorrectOperationException e) {
127 throw e;
129 catch (Exception e) {
130 LOG.error(e);
131 return null;
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);
156 * @not_implemented
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);
182 if (level == null) {
183 level = getLanguageLevelInner(dir);
184 dir.putUserData(LANG_LEVEL_IN_DIRECTORY, level);
186 return 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();