| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * Portions Copyright 2000-2004 The Apache Software Foundation |
| * All rights reserved. This program and the accompanying materials are made |
| * available under the terms of the Apache Software License v2.0 which |
| * accompanies this distribution and is available at |
| * http://www.apache.org/licenses/LICENSE-2.0. |
| * |
| * Contributors: |
| * IBM Corporation - derived implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ant.internal.ui.model; |
| |
| import java.io.File; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.apache.tools.ant.AntClassLoader; |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.BuildListener; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.PropertyHelper; |
| import org.apache.tools.ant.UnknownElement; |
| import org.apache.tools.ant.types.Path; |
| import org.eclipse.ant.internal.core.IAntCoreConstants; |
| |
| /** |
| * Derived from the original Ant Project class |
| * This class allows property values to be written multiple times. |
| * This facilitates incremental parsing of the Ant build file |
| * It also attempts to ensure that we clean up after ourselves and allows |
| * more manipulation of properties resulting from incremental parsing. |
| * Also allows the Eclipse additions to the Ant runtime classpath. |
| */ |
| public class AntModelProject extends Project { |
| |
| /** |
| * Delegate to maintain property chaining - to make sure our project is alerted |
| * to new properties being set |
| */ |
| class AntPropertyHelper implements PropertyHelper.PropertySetter { |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.PropertyHelper.PropertySetter#setNew(java.lang.String, java.lang.Object, org.apache.tools.ant.PropertyHelper) |
| */ |
| public boolean setNew(String property, Object value, PropertyHelper propertyHelper) { |
| setNewProperty(property, value.toString()); |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.PropertyHelper.PropertySetter#set(java.lang.String, java.lang.Object, org.apache.tools.ant.PropertyHelper) |
| */ |
| public boolean set(String property, Object value, PropertyHelper propertyHelper) { |
| return false; |
| } |
| } |
| |
| private AntPropertyNode fCurrentConfiguringPropertyNode; |
| private Map idrefs = Collections.synchronizedMap(new HashMap()); |
| private static Object loaderLock = new Object(); |
| private Hashtable loaders = null; |
| private AntRefTable references = new AntRefTable(); |
| |
| /** |
| * Constructor |
| * <p> |
| * Allows us to register a {@link PropertyHelper.PropertySetter} delegate for this project |
| * </p> |
| * @noreference This constructor is not intended to be referenced by clients. |
| */ |
| public AntModelProject() { |
| PropertyHelper.getPropertyHelper(this).add(new AntPropertyHelper()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#setNewProperty(java.lang.String, java.lang.String) |
| */ |
| public void setNewProperty(String name, String value) { |
| if(PropertyHelper.getPropertyHelper(this).getProperty(name) != null) { |
| return; |
| } |
| //allows property values to be over-written for this parse session |
| //there is currently no way to remove properties from the Apache Ant project |
| //the project resets it properties for each parse...see reset() |
| if (fCurrentConfiguringPropertyNode != null) { |
| fCurrentConfiguringPropertyNode.addProperty(name, value); |
| } |
| super.setProperty(name, value); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#fireBuildFinished(java.lang.Throwable) |
| */ |
| public void fireBuildFinished(Throwable exception) { |
| super.fireBuildFinished(exception); |
| Enumeration e= getBuildListeners().elements(); |
| while (e.hasMoreElements()) { |
| BuildListener listener = (BuildListener) e.nextElement(); |
| removeBuildListener(listener); |
| } |
| } |
| |
| /** |
| * Reset the project |
| */ |
| public void reset() { |
| getTargets().clear(); |
| setDefault(null); |
| setDescription(null); |
| setName(IAntCoreConstants.EMPTY_STRING); |
| synchronized (loaderLock) { |
| if(loaders != null) { |
| Iterator i = loaders.entrySet().iterator(); |
| Entry e = null; |
| while(i.hasNext()) { |
| e = (Entry) i.next(); |
| AntClassLoader acl = (AntClassLoader) e.getValue(); |
| acl.cleanup(); |
| acl.clearAssertionStatus(); |
| } |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#getProperty(java.lang.String) |
| */ |
| public String getProperty(String name) { |
| //override as we cannot remove properties from the Apache Ant project |
| String result= super.getProperty(name); |
| if (result == null) { |
| return getUserProperty(name); |
| } |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#addIdReference(java.lang.String, java.lang.Object) |
| */ |
| public void addIdReference(String id, Object value) { |
| //XXX hack because we cannot look up references by id in Ant 1.8.x |
| //see https://issues.apache.org/bugzilla/show_bug.cgi?id=49659 |
| idrefs.put(id, value); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#getReference(java.lang.String) |
| */ |
| public Object getReference(String key) { |
| Object ref = references.get(key); |
| if(ref == null) { |
| ref = idrefs.get(key); |
| if(ref instanceof UnknownElement) { |
| UnknownElement ue = (UnknownElement) ref; |
| ue.maybeConfigure(); |
| return ue.getRealThing(); |
| } |
| } |
| return ref; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#getProperties() |
| */ |
| public Hashtable getProperties() { |
| //override as we cannot remove properties from the Apache Ant project |
| Hashtable allProps = super.getProperties(); |
| allProps.putAll(getUserProperties()); |
| allProps.put("basedir", getBaseDir().getPath()); //$NON-NLS-1$ |
| return allProps; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#setBaseDir(java.io.File) |
| */ |
| public void setBaseDir(File baseDir) throws BuildException { |
| super.setBaseDir(baseDir); |
| setNewProperty("basedir", getBaseDir().getPath()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param node the property node that is currently being configured |
| */ |
| public void setCurrentConfiguringProperty(AntPropertyNode node) { |
| fCurrentConfiguringPropertyNode= node; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#createClassLoader(org.apache.tools.ant.types.Path) |
| */ |
| public AntClassLoader createClassLoader(Path path) { |
| synchronized (loaderLock) { |
| if(loaders == null) { |
| loaders = new Hashtable(8); |
| } |
| Path p = path; |
| if(p == null) { |
| p = new Path(this); |
| } |
| String pstr = p.toString(); |
| AntClassLoader loader = (AntClassLoader) loaders.get(pstr); |
| if(loader == null) { |
| loader = super.createClassLoader(path); |
| if (path == null) { |
| //use the "fake" Eclipse runtime classpath for Ant |
| loader.setClassPath(Path.systemClasspath); |
| } |
| loaders.put(pstr, loader); |
| } |
| return loader; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#addReference(java.lang.String, java.lang.Object) |
| */ |
| public void addReference(String referenceName, Object value) { |
| references.put(referenceName, value); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#getReferences() |
| */ |
| public Hashtable getReferences() { |
| return references; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#getCopyOfReferences() |
| */ |
| public Map getCopyOfReferences() { |
| return new Hashtable(references); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.Project#hasReference(java.lang.String) |
| */ |
| public boolean hasReference(String key) { |
| return references.contains(key); |
| } |
| } |