ant support over DOM2, in progress...

This commit is contained in:
Eugene Zhuravlev
2010-04-12 10:55:16 +04:00
parent 1ceaf0cbf7
commit af5b6a6e07
14 changed files with 336 additions and 124 deletions
+4
View File
@@ -38,6 +38,10 @@
implementationClass="com.intellij.lang.ant.AntDeclarationRangeHandler"/>
<refactoring.elementListenerProvider implementation="com.intellij.lang.ant.refactoring.AntTargetRenameListenerProvider"/>
<inspectionToolProvider implementation="com.intellij.lang.ant.AntInspectionToolProvider"/>
<dom.fileDescription implementation="com.intellij.lang.ant.dom.AntDomFileDescription"/>
<dom.extender domClass="com.intellij.lang.ant.dom.AntDomElement" extenderClass="com.intellij.lang.ant.dom.AntDomExtender"/>
</extensions>
<application-components>
@@ -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();
@@ -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) {
@@ -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<AntBuildFile> ANT_BUILD_FILE_KEY = Key.create("ANT_BUILD_FILE");
@Nullable
String getPresentableName();
@@ -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) {
@@ -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<AntDomElement> 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;
}
}
@@ -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<AntDomElement>{
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<String> names = new HashSet<String>();
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;
}
}
@@ -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<AntDomProject> {
}
protected void initializeFileDescription() {
// todo
registerReferenceInjector(new AntReferenceInjector());
}
public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) {
@@ -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<String> getName();
public abstract GenericAttributeValue<String> getName();
@Attribute("default")
GenericAttributeValue<String> getDefaultTargetName();
public abstract GenericAttributeValue<String> getDefaultTargetName();
@Attribute("basedir")
GenericAttributeValue<String> getBasedir();
public abstract GenericAttributeValue<String> getBasedir();
@SubTagList("target")
List<AntTarget> getTargets();
public abstract List<AntTarget> 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;
}
}
@@ -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;
}
}
@@ -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<String> getName();
public abstract GenericAttributeValue<String> getName();
@Attribute("if")
GenericAttributeValue<String> getIfPropertyName();
public abstract GenericAttributeValue<String> getIfPropertyName();
@Attribute("unless")
GenericAttributeValue<String> getUnlessPropertyName();
public abstract GenericAttributeValue<String> getUnlessPropertyName();
}
@@ -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{
}
@@ -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<AntTypeId, String> 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<String, AntTypeDefinition>();
myProjectElements = new HashMap<AntTypeId, String>();
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<SoftReference<Pair<ReflectedProject, ClassLoader>>> ourProjects =
new ArrayList<SoftReference<Pair<ReflectedProject, ClassLoader>>>();
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<SoftReference<Pair<ReflectedProject, ClassLoader>>> iterator = ourProjects.iterator(); iterator.hasNext();) {
final SoftReference<Pair<ReflectedProject, ClassLoader>> ref = iterator.next();
final Pair<ReflectedProject, ClassLoader> 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<Pair<ReflectedProject, ClassLoader>>(
new Pair<ReflectedProject, ClassLoader>(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<PsiFile> myDependentFiles;
private final long[] myStamps;
@@ -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<SoftReference<Pair<ReflectedProject, ClassLoader>>> ourProjects =
new ArrayList<SoftReference<Pair<ReflectedProject, ClassLoader>>>();
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<SoftReference<Pair<ReflectedProject, ClassLoader>>> iterator = ourProjects.iterator(); iterator.hasNext();) {
final SoftReference<Pair<ReflectedProject, ClassLoader>> ref = iterator.next();
final Pair<ReflectedProject, ClassLoader> 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<Pair<ReflectedProject, ClassLoader>>(
new Pair<ReflectedProject, ClassLoader>(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;
}
}