0a927ff7e5f240201d1fa0aa4196d84415bcacfc
[idea/community.git] / plugins / ant / src / com / intellij / lang / ant / AntSupport.java
1 /*
2  * Copyright 2000-2009 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 package com.intellij.lang.ant;
17
18 import com.intellij.lang.CompositeLanguage;
19 import com.intellij.lang.StdLanguages;
20 import com.intellij.lang.ant.dom.AntDomElement;
21 import com.intellij.lang.ant.dom.AntDomProject;
22 import com.intellij.lang.ant.psi.AntFile;
23 import com.intellij.lang.ant.psi.changes.AntChangeVisitor;
24 import com.intellij.lang.xml.XMLLanguage;
25 import com.intellij.openapi.components.ApplicationComponent;
26 import com.intellij.openapi.fileTypes.FileType;
27 import com.intellij.openapi.fileTypes.FileTypeManager;
28 import com.intellij.openapi.fileTypes.LanguageFileType;
29 import com.intellij.openapi.project.Project;
30 import com.intellij.openapi.vfs.VirtualFile;
31 import com.intellij.psi.FileViewProvider;
32 import com.intellij.psi.PsiFile;
33 import com.intellij.psi.PsiManager;
34 import com.intellij.psi.xml.XmlFile;
35 import com.intellij.psi.xml.XmlTag;
36 import com.intellij.util.xml.ConvertContext;
37 import com.intellij.util.xml.DomElement;
38 import com.intellij.util.xml.DomFileElement;
39 import com.intellij.util.xml.DomManager;
40 import org.jetbrains.annotations.NonNls;
41 import org.jetbrains.annotations.NotNull;
42 import org.jetbrains.annotations.Nullable;
43
44 import java.util.*;
45
46 public class AntSupport implements ApplicationComponent {
47   private static LanguageFileType ourFileType = null;
48   private static AntLanguage ourLanguage = null;
49   private static AntChangeVisitor ourChangeVisitor = null;
50   private static final Map<AntFile, WeakHashMap<AntFile, Boolean>> ourFileDependencies = new WeakHashMap<AntFile, WeakHashMap<AntFile, Boolean>>();
51
52   public AntSupport(FileTypeManager fileTypeManager) {
53     fileTypeManager.getRegisteredFileTypes();
54     ((CompositeLanguage)StdLanguages.XML).registerLanguageExtension(new AntLanguageExtension());
55   }
56
57   public static synchronized AntLanguage getLanguage() {
58     if (ourLanguage == null) {
59       if (ourFileType == null) {
60         ourFileType = new AntFileType();
61       }
62       ourLanguage = (AntLanguage)ourFileType.getLanguage();
63     }
64     return ourLanguage;
65   }
66
67   public static synchronized AntChangeVisitor getChangeVisitor() {
68     if (ourChangeVisitor == null) {
69       ourChangeVisitor = new AntChangeVisitor();
70     }
71     return ourChangeVisitor;
72   }
73
74   @NotNull
75   @NonNls
76   public String getComponentName() {
77     return "AntSupport";
78   }
79
80   public void initComponent() {
81   }
82
83   public void disposeComponent() {
84   }
85
86   public static void markFileAsAntFile(final VirtualFile file, final FileViewProvider viewProvider, final boolean value) {
87     if (file.isValid() && ForcedAntFileAttribute.isAntFile(file) != value) {
88       ForcedAntFileAttribute.forceAntFile(file, value);
89       viewProvider.contentsSynchronized();
90     }
91   }
92
93   //
94   // Managing ant files dependencies via the <import> task.
95   //
96
97   public static synchronized List<AntFile> getImportingFiles(final AntFile imported) {
98     final WeakHashMap<AntFile, Boolean> files = ourFileDependencies.get(imported);
99     if (files != null) {
100       final int size = files.size();
101       if (size > 0) {
102         final List<AntFile> result = new ArrayList<AntFile>(size);
103         for (final AntFile file : files.keySet()) {
104           if (file != null) {
105             result.add(file);
106           }
107         }
108         return result;
109       }
110     }
111     return Collections.emptyList();
112   }
113
114   public static synchronized void registerDependency(final AntFile importing, final AntFile imported) {
115     final Map<AntFile, WeakHashMap<AntFile,Boolean>> dependencies = ourFileDependencies;
116     WeakHashMap<AntFile, Boolean> files = dependencies.get(imported);
117     if(files == null) {
118       files = new WeakHashMap<AntFile, Boolean>();
119       dependencies.put(imported, files);
120     }
121     files.put(importing, true);
122   }
123
124   public static AntFile getAntFile ( PsiFile psiFile ) {
125     if (psiFile instanceof AntFile) {
126       return (AntFile)psiFile;
127     }
128     else {
129       return (AntFile)psiFile.getViewProvider().getPsi(getLanguage());
130     }
131   }
132
133   @Nullable
134   public static AntDomProject getAntDomProject(PsiFile psiFile) {
135     if (psiFile instanceof XmlFile) {
136       final DomManager domManager = DomManager.getDomManager(psiFile.getProject());
137       final DomFileElement<AntDomProject> fileElement = domManager.getFileElement((XmlFile)psiFile, AntDomProject.class);
138       return fileElement != null? fileElement.getRootElement() : null;
139     }
140     return null;
141   }
142
143   @Nullable
144   public static AntDomElement getAntDomElement(XmlTag xmlTag) {
145     final DomElement domElement = DomManager.getDomManager(xmlTag.getProject()).getDomElement(xmlTag);
146     return domElement instanceof AntDomElement? (AntDomElement)domElement : null;
147   }
148
149   @Nullable
150   public static AntFile toAntFile(VirtualFile vFile, final Project project) {
151     if (vFile == null) {
152       return null;
153     }
154     final FileType fileType = vFile.getFileType();
155     if (fileType instanceof AntFileType || XMLLanguage.INSTANCE.getAssociatedFileType() == fileType) {
156       final PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
157       return psiFile != null? getAntFile(psiFile) : null;
158     }
159     return null;
160   }
161
162   @Nullable
163   public static AntDomElement getInvocationAntDomElement(ConvertContext context) {
164     return context.getInvocationElement().getParentOfType(AntDomElement.class, false);
165   }
166 }