From af5b6a6e0731cbb40b3a05057827da5919793154 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 12 Apr 2010 10:55:16 +0400 Subject: [PATCH] ant support over DOM2, in progress... --- plugins/ant/src/META-INF/plugin.xml | 4 + .../lang/ant/AntDefaultNSProvider.java | 3 +- .../src/com/intellij/lang/ant/AntSupport.java | 12 ++ .../lang/ant/config/AntBuildFile.java | 3 + .../ant/config/impl/AntConfigurationImpl.java | 5 +- .../intellij/lang/ant/dom/AntDomElement.java | 30 ++++- .../intellij/lang/ant/dom/AntDomExtender.java | 68 ++++++++++ .../lang/ant/dom/AntDomFileDescription.java | 3 +- .../intellij/lang/ant/dom/AntDomProject.java | 43 +++++- .../lang/ant/dom/AntReferenceInjector.java | 40 ++++++ .../com/intellij/lang/ant/dom/AntTarget.java | 10 +- .../com/intellij/lang/ant/dom/AntTask.java | 23 ---- .../lang/ant/psi/impl/AntFileImpl.java | 93 ++----------- .../lang/ant/psi/impl/ReflectedProject.java | 123 ++++++++++++++++++ 14 files changed, 336 insertions(+), 124 deletions(-) create mode 100644 plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java create mode 100644 plugins/ant/src/com/intellij/lang/ant/dom/AntReferenceInjector.java delete mode 100644 plugins/ant/src/com/intellij/lang/ant/dom/AntTask.java create mode 100644 plugins/ant/src/com/intellij/lang/ant/psi/impl/ReflectedProject.java diff --git a/plugins/ant/src/META-INF/plugin.xml b/plugins/ant/src/META-INF/plugin.xml index a5e3b197a305..73786be29097 100644 --- a/plugins/ant/src/META-INF/plugin.xml +++ b/plugins/ant/src/META-INF/plugin.xml @@ -38,6 +38,10 @@ implementationClass="com.intellij.lang.ant.AntDeclarationRangeHandler"/> + + + + diff --git a/plugins/ant/src/com/intellij/lang/ant/AntDefaultNSProvider.java b/plugins/ant/src/com/intellij/lang/ant/AntDefaultNSProvider.java index 26d85dfb3d19..19316aa593cf 100644 --- a/plugins/ant/src/com/intellij/lang/ant/AntDefaultNSProvider.java +++ b/plugins/ant/src/com/intellij/lang/ant/AntDefaultNSProvider.java @@ -15,6 +15,7 @@ */ package com.intellij.lang.ant; +import com.intellij.lang.ant.config.AntBuildFile; import com.intellij.lang.ant.psi.impl.AntFileImpl; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.xml.XmlDocument; @@ -34,7 +35,7 @@ public class AntDefaultNSProvider implements XmlFileNSInfoProvider { // nsPrefix, namespaceId public String[][] getDefaultNamespaces(@NotNull XmlFile xmlFile) { - if (xmlFile.getCopyableUserData(AntFileImpl.ANT_BUILD_FILE) != null) return myNamespaces; + if (xmlFile.getCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY) != null) return myNamespaces; final XmlDocument document = xmlFile.getDocument(); if (document != null) { final XmlTag tag = document.getRootTag(); diff --git a/plugins/ant/src/com/intellij/lang/ant/AntSupport.java b/plugins/ant/src/com/intellij/lang/ant/AntSupport.java index 3808cb351901..f08d65c8ce6a 100644 --- a/plugins/ant/src/com/intellij/lang/ant/AntSupport.java +++ b/plugins/ant/src/com/intellij/lang/ant/AntSupport.java @@ -17,6 +17,7 @@ package com.intellij.lang.ant; import com.intellij.lang.CompositeLanguage; import com.intellij.lang.StdLanguages; +import com.intellij.lang.ant.dom.AntDomProject; import com.intellij.lang.ant.psi.AntFile; import com.intellij.lang.ant.psi.changes.AntChangeVisitor; import com.intellij.lang.xml.XMLLanguage; @@ -29,6 +30,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.xml.DomManager; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -122,6 +125,15 @@ public class AntSupport implements ApplicationComponent { } } + @Nullable + public static AntDomProject getAntDomProject(PsiFile psiFile) { + if (psiFile instanceof XmlFile) { + final DomManager domManager = DomManager.getDomManager(psiFile.getProject()); + return domManager.getFileElement((XmlFile)psiFile, AntDomProject.class).getRootElement(); + } + return null; + } + @Nullable public static AntFile toAntFile(VirtualFile vFile, final Project project) { if (vFile == null) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/AntBuildFile.java b/plugins/ant/src/com/intellij/lang/ant/config/AntBuildFile.java index baa06bffc808..9a5c9cb0e4bc 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/AntBuildFile.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/AntBuildFile.java @@ -17,11 +17,14 @@ package com.intellij.lang.ant.config; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.Nullable; public interface AntBuildFile { + Key ANT_BUILD_FILE_KEY = Key.create("ANT_BUILD_FILE"); + @Nullable String getPresentableName(); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java index 735ed76b140b..e33529f8109d 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java @@ -26,7 +26,6 @@ import com.intellij.lang.ant.AntSupport; import com.intellij.lang.ant.config.*; import com.intellij.lang.ant.config.actions.TargetAction; import com.intellij.lang.ant.psi.AntFile; -import com.intellij.lang.ant.psi.impl.AntFileImpl; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -546,7 +545,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } final AntFile antFile = (AntFile)psiFile; final AntBuildFileImpl buildFile = new AntBuildFileImpl(antFile, this); - antFile.getSourceElement().putCopyableUserData(AntFileImpl.ANT_BUILD_FILE, buildFile); + antFile.getSourceElement().putCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY, buildFile); synchronized (myBuildFiles) { myBuildFilesArray = null; myBuildFiles.add(buildFile); @@ -609,7 +608,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis final AntFile antFile = (AntFile)buildFile.getAntFile(); if (antFile != null) { final XmlFile xmlFile = antFile.getSourceElement(); - xmlFile.putCopyableUserData(AntFileImpl.ANT_BUILD_FILE, null); + xmlFile.putCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY, null); AntSupport.markFileAsAntFile(xmlFile.getVirtualFile(), xmlFile.getViewProvider(), false); } synchronized (myBuildFiles) { diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomElement.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomElement.java index f464250e1598..f9484d84fef4 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomElement.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomElement.java @@ -15,11 +15,39 @@ */ package com.intellij.lang.ant.dom; +import com.intellij.lang.ant.psi.introspection.AntTypeDefinition; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomUtil; + +import java.util.List; /** * @author Eugene Zhuravlev * Date: Apr 6, 2010 */ -public interface AntDomElement extends DomElement { +@SuppressWarnings({"AbstractClassNeverImplemented"}) +public abstract class AntDomElement implements DomElement { + + public final AntTypeDefinition getAntType() { + // todo + return null; + } + + public final List getAntChildren() { + return DomUtil.getDefinedChildrenOfType(this, AntDomElement.class, true, false); + } + + public String toString() { + final XmlTag tag = getXmlTag(); + if (tag == null) { + return super.toString(); + } + final String name = tag.getName(); + if ("".equals(name)) { + return super.toString(); + } + return name; + } + } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java new file mode 100644 index 000000000000..9a57aac3b332 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2010 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 com.intellij.lang.ant.dom; + +import com.intellij.lang.ant.psi.impl.AntIntrospector; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.xml.XmlName; +import com.intellij.util.xml.reflect.DomExtender; +import com.intellij.util.xml.reflect.DomExtensionsRegistrar; +import com.intellij.util.xml.reflect.DomGenericInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Eugene Zhuravlev + * Date: Apr 9, 2010 + */ +public class AntDomExtender extends DomExtender{ + public void registerExtensions(@NotNull AntDomElement antDomElement, @NotNull DomExtensionsRegistrar registrar) { + final XmlElement xmlElement = antDomElement.getXmlElement(); + if (xmlElement instanceof XmlTag) { + + //final AntDomProject antProject = antDomElement.getParentOfType(AntDomProject.class, false); + //assert antProject != null; + //final ReflectedProject reflected = ReflectedProject.getProject(antProject.getClassLoader()); + + final Set names = new HashSet(); + for (XmlTag tag : ((XmlTag)xmlElement).getSubTags()) { + names.add(tag.getName()); + } + final DomGenericInfo genericInfo = antDomElement.getGenericInfo(); + for (String name : names) { + if (genericInfo.getCollectionChildDescription(name) == null) { // not defined yet + registrar.registerCollectionChildrenExtension(new XmlName(name), AntDomElement.class); + } + } + } + } + + + @Nullable + private static AntIntrospector getIntrospector(Class c) { + try { + return AntIntrospector.getInstance(c); + } + catch (Throwable ignored) { + } + return null; + } + +} diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileDescription.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileDescription.java index 3b28b669878d..376f0a8b06f3 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileDescription.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileDescription.java @@ -18,7 +18,6 @@ package com.intellij.lang.ant.dom; import com.intellij.lang.ant.AntLanguageExtension; import com.intellij.openapi.module.Module; import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.DomFileDescription; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,7 +32,7 @@ public class AntDomFileDescription extends DomFileDescription { } protected void initializeFileDescription() { - // todo + registerReferenceInjector(new AntReferenceInjector()); } public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) { diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomProject.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomProject.java index d6b795e3a276..8c373b5afe33 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomProject.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomProject.java @@ -15,9 +15,16 @@ */ package com.intellij.lang.ant.dom; +import com.intellij.lang.ant.config.AntBuildFile; +import com.intellij.lang.ant.config.AntConfigurationBase; +import com.intellij.lang.ant.config.impl.AntBuildFileImpl; +import com.intellij.lang.ant.config.impl.AntInstallation; +import com.intellij.lang.ant.config.impl.GlobalAntConfiguration; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.Attribute; import com.intellij.util.xml.GenericAttributeValue; import com.intellij.util.xml.SubTagList; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -25,17 +32,43 @@ import java.util.List; * @author Eugene Zhuravlev * Date: Apr 6, 2010 */ -public interface AntDomProject extends AntDomElement { +@SuppressWarnings({"AbstractClassNeverImplemented"}) +public abstract class AntDomProject extends AntDomElement { + private ClassLoader myClassLoader; @Attribute("name") - GenericAttributeValue getName(); + public abstract GenericAttributeValue getName(); @Attribute("default") - GenericAttributeValue getDefaultTargetName(); + public abstract GenericAttributeValue getDefaultTargetName(); @Attribute("basedir") - GenericAttributeValue getBasedir(); + public abstract GenericAttributeValue getBasedir(); @SubTagList("target") - List getTargets(); + public abstract List getTargets(); + + @NotNull + public final ClassLoader getClassLoader() { + if (myClassLoader == null) { + final XmlTag tag = getXmlTag(); + final AntBuildFileImpl buildFile = (AntBuildFileImpl)tag.getCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY); + if (buildFile != null) { + myClassLoader = buildFile.getClassLoader(); + } + else { + final AntConfigurationBase configuration = AntConfigurationBase.getInstance(tag.getProject()); + AntInstallation antInstallation = null; + if (configuration != null) { + antInstallation = configuration.getProjectDefaultAnt(); + } + if (antInstallation == null) { + antInstallation = GlobalAntConfiguration.getInstance().getBundledAnt(); + } + assert antInstallation != null; + myClassLoader = antInstallation.getClassLoader(); + } + } + return myClassLoader; + } } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntReferenceInjector.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntReferenceInjector.java new file mode 100644 index 000000000000..6b4cbca38fb9 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntReferenceInjector.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2010 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 com.intellij.lang.ant.dom; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomReferenceInjector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* @author Eugene Zhuravlev +* Date: Apr 9, 2010 +*/ +class AntReferenceInjector implements DomReferenceInjector { + public String resolveString(@Nullable String unresolvedText, @NotNull ConvertContext context) { + final DomElement element = context.getInvocationElement(); + return null; + } + + @NotNull + public PsiReference[] inject(@Nullable String unresolvedText, @NotNull PsiElement element, @NotNull ConvertContext context) { + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntTarget.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntTarget.java index 7b48df852806..534496e99eab 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntTarget.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntTarget.java @@ -17,19 +17,19 @@ package com.intellij.lang.ant.dom; import com.intellij.util.xml.Attribute; import com.intellij.util.xml.GenericAttributeValue; -import com.intellij.util.xml.SubTagList; /** * @author Eugene Zhuravlev * Date: Apr 6, 2010 */ -public interface AntTarget extends AntDomElement{ +@SuppressWarnings({"AbstractClassNeverImplemented"}) +public abstract class AntTarget extends AntDomElement { @Attribute("name") - GenericAttributeValue getName(); + public abstract GenericAttributeValue getName(); @Attribute("if") - GenericAttributeValue getIfPropertyName(); + public abstract GenericAttributeValue getIfPropertyName(); @Attribute("unless") - GenericAttributeValue getUnlessPropertyName(); + public abstract GenericAttributeValue getUnlessPropertyName(); } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntTask.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntTask.java deleted file mode 100644 index 2ac9a9092483..000000000000 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntTask.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2000-2010 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 com.intellij.lang.ant.dom; - -/** - * @author Eugene Zhuravlev - * Date: Apr 6, 2010 - */ -public interface AntTask extends AntDomElement{ -} diff --git a/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntFileImpl.java b/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntFileImpl.java index 26aa44af6743..f0d1f9e7df88 100644 --- a/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntFileImpl.java +++ b/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntFileImpl.java @@ -19,6 +19,7 @@ import com.intellij.extapi.psi.LightPsiFileBase; import com.intellij.lang.StdLanguages; import com.intellij.lang.ant.AntElementRole; import com.intellij.lang.ant.AntSupport; +import com.intellij.lang.ant.config.AntBuildFile; import com.intellij.lang.ant.config.AntConfiguration; import com.intellij.lang.ant.config.AntConfigurationBase; import com.intellij.lang.ant.config.impl.AntBuildFileImpl; @@ -37,8 +38,6 @@ import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; @@ -62,8 +61,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; import java.io.IOException; -import java.lang.ref.SoftReference; -import java.lang.reflect.Method; import java.util.*; @SuppressWarnings({"UseOfObsoleteCollectionType"}) @@ -123,7 +120,6 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { */ private volatile HashMap myProjectElements; private long myModificationCount = 0; - public static final Key ANT_BUILD_FILE = Key.create("ANT_BUILD_FILE"); public AntFileImpl(final FileViewProvider viewProvider) { super(viewProvider, AntSupport.getLanguage()); @@ -305,7 +301,7 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { @NotNull public ClassLoader getClassLoader() { if (myClassLoader == null) { - final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(ANT_BUILD_FILE); + final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY); if (buildFile != null) { myClassLoader = buildFile.getClassLoader(); } @@ -327,7 +323,7 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { @NotNull public AntInstallation getAntInstallation() { - final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(ANT_BUILD_FILE); + final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY); if (buildFile != null) { final AntInstallation assignedInstallation = AntBuildFileImpl.ANT_INSTALLATION.get(buildFile.getAllOptions()); if (assignedInstallation != null) { @@ -348,7 +344,7 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { @Nullable public Sdk getTargetJdk() { - final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(ANT_BUILD_FILE); + final AntBuildFileImpl buildFile = (AntBuildFileImpl)getSourceElement().getCopyableUserData(AntBuildFile.ANT_BUILD_FILE_KEY); if (buildFile == null) { return ProjectRootManager.getInstance(getProject()).getProjectJdk(); } @@ -764,12 +760,12 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { myTypeDefinitions = new HashMap(); myProjectElements = new HashMap(); final ReflectedProject reflectedProject = ReflectedProject.getProject(getClassLoader()); - if (reflectedProject.myProject != null) { + if (reflectedProject.getProject() != null) { //first, create task definitons - updateTypeDefinitions(reflectedProject.myTaskDefinitions, true); + updateTypeDefinitions(reflectedProject.getTaskDefinitions(), true); // second, create definitions of data types - updateTypeDefinitions(reflectedProject.myDataTypeDefinitions, false); - myProjectProperties = reflectedProject.myProperties; + updateTypeDefinitions(reflectedProject.getDataTypeDefinitions(), false); + myProjectProperties = reflectedProject.getProperties(); } } } @@ -779,7 +775,7 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { synchronized (PsiLock.LOCK) { buildTypeDefinitions(); if (myTargetDefinition == null) { - final Class targetClass = ReflectedProject.getProject(getClassLoader()).myTargetClass; + final Class targetClass = ReflectedProject.getProject(getClassLoader()).getTargetClass(); final AntTypeDefinition targetDef = createTypeDefinition(new AntTypeId(TARGET_TAG), targetClass, false); if (targetDef != null) { for (final AntTypeDefinition def : getBaseTypeDefinitions()) { @@ -991,77 +987,6 @@ public class AntFileImpl extends LightPsiFileBase implements AntFile { return getRole().getIcon(); } - private static final class ReflectedProject { - - @NonNls private static final String INIT_METHOD_NAME = "init"; - @NonNls private static final String GET_TASK_DEFINITIONS_METHOD_NAME = "getTaskDefinitions"; - @NonNls private static final String GET_DATA_TYPE_DEFINITIONS_METHOD_NAME = "getDataTypeDefinitions"; - @NonNls private static final String GET_PROPERTIES_METHOD_NAME = "getProperties"; - - - private static final List>> ourProjects = - new ArrayList>>(); - - private final Object myProject; - private Hashtable myTaskDefinitions; - private Hashtable myDataTypeDefinitions; - private Hashtable myProperties; - private Class myTargetClass; - - private static ReflectedProject getProject(final ClassLoader classLoader) { - for (Iterator>> iterator = ourProjects.iterator(); iterator.hasNext();) { - final SoftReference> ref = iterator.next(); - final Pair pair = ref.get(); - if (pair == null) { - iterator.remove(); - } - else { - if (pair.second == classLoader) { - return pair.first; - } - } - } - final ReflectedProject project = new ReflectedProject(classLoader); - ourProjects.add(new SoftReference>( - new Pair(project, classLoader) - )); - return project; - } - - private ReflectedProject(final ClassLoader classLoader) { - Object myProject = null; - try { - final Class projectClass = classLoader.loadClass("org.apache.tools.ant.Project"); - if (projectClass != null) { - myProject = projectClass.newInstance(); - Method method = projectClass.getMethod(INIT_METHOD_NAME); - method.invoke(myProject); - method = getMethod(projectClass, GET_TASK_DEFINITIONS_METHOD_NAME); - myTaskDefinitions = (Hashtable)method.invoke(myProject); - method = getMethod(projectClass, GET_DATA_TYPE_DEFINITIONS_METHOD_NAME); - myDataTypeDefinitions = (Hashtable)method.invoke(myProject); - method = getMethod(projectClass, GET_PROPERTIES_METHOD_NAME); - myProperties = (Hashtable)method.invoke(myProject); - myTargetClass = classLoader.loadClass("org.apache.tools.ant.Target"); - } - } - catch (Exception e) { - LOG.info(e); - myProject = null; - } - this.myProject = myProject; - } - - private static Method getMethod(final Class introspectionHelperClass, final String name) throws NoSuchMethodException { - final Method method; - method = introspectionHelperClass.getMethod(name); - if (!method.isAccessible()) { - method.setAccessible(true); - } - return method; - } - } - private static class PropertiesWatcher { private final List myDependentFiles; private final long[] myStamps; diff --git a/plugins/ant/src/com/intellij/lang/ant/psi/impl/ReflectedProject.java b/plugins/ant/src/com/intellij/lang/ant/psi/impl/ReflectedProject.java new file mode 100644 index 000000000000..9ff927df633d --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/psi/impl/ReflectedProject.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2010 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 com.intellij.lang.ant.psi.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NonNls; + +import java.lang.ref.SoftReference; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; + +/** +* @author Eugene Zhuravlev +* Date: Apr 9, 2010 +*/ +public final class ReflectedProject { + private static final Logger LOG = Logger.getInstance("#com.intellij.lang.ant.psi.impl.ReflectedProject"); + + @NonNls private static final String INIT_METHOD_NAME = "init"; + @NonNls private static final String GET_TASK_DEFINITIONS_METHOD_NAME = "getTaskDefinitions"; + @NonNls private static final String GET_DATA_TYPE_DEFINITIONS_METHOD_NAME = "getDataTypeDefinitions"; + @NonNls private static final String GET_PROPERTIES_METHOD_NAME = "getProperties"; + + + private static final List>> ourProjects = + new ArrayList>>(); + + private final Object myProject; + private Hashtable myTaskDefinitions; + private Hashtable myDataTypeDefinitions; + private Hashtable myProperties; + private Class myTargetClass; + + public static ReflectedProject getProject(final ClassLoader classLoader) { + for (Iterator>> iterator = ourProjects.iterator(); iterator.hasNext();) { + final SoftReference> ref = iterator.next(); + final Pair pair = ref.get(); + if (pair == null) { + iterator.remove(); + } + else { + if (pair.second == classLoader) { + return pair.first; + } + } + } + final ReflectedProject project = new ReflectedProject(classLoader); + ourProjects.add(new SoftReference>( + new Pair(project, classLoader) + )); + return project; + } + + ReflectedProject(final ClassLoader classLoader) { + Object myProject = null; + try { + final Class projectClass = classLoader.loadClass("org.apache.tools.ant.Project"); + if (projectClass != null) { + myProject = projectClass.newInstance(); + Method method = projectClass.getMethod(INIT_METHOD_NAME); + method.invoke(myProject); + method = getMethod(projectClass, GET_TASK_DEFINITIONS_METHOD_NAME); + myTaskDefinitions = (Hashtable)method.invoke(myProject); + method = getMethod(projectClass, GET_DATA_TYPE_DEFINITIONS_METHOD_NAME); + myDataTypeDefinitions = (Hashtable)method.invoke(myProject); + method = getMethod(projectClass, GET_PROPERTIES_METHOD_NAME); + myProperties = (Hashtable)method.invoke(myProject); + myTargetClass = classLoader.loadClass("org.apache.tools.ant.Target"); + } + } + catch (Exception e) { + LOG.info(e); + myProject = null; + } + this.myProject = myProject; + } + + private static Method getMethod(final Class introspectionHelperClass, final String name) throws NoSuchMethodException { + final Method method; + method = introspectionHelperClass.getMethod(name); + if (!method.isAccessible()) { + method.setAccessible(true); + } + return method; + } + + public Hashtable getTaskDefinitions() { + return myTaskDefinitions; + } + + public Hashtable getDataTypeDefinitions() { + return myDataTypeDefinitions; + } + + public Hashtable getProperties() { + return myProperties; + } + + public Class getTargetClass() { + return myTargetClass; + } + + public Object getProject() { + return myProject; + } +}