You are viewing a plain text version of this content. The canonical link for it is here.
Posted to easyant-commits@incubator.apache.org by hi...@apache.org on 2011/02/17 17:01:56 UTC
svn commit: r1071697 [23/42] - in /incubator/easyant: buildtypes/
buildtypes/trunk/ buildtypes/trunk/build-osgi-bundle-java/
buildtypes/trunk/build-osgi-bundle-java/src/
buildtypes/trunk/build-osgi-bundle-java/src/main/
buildtypes/trunk/build-osgi-bund...
Added: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java (added)
+++ incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java Thu Feb 17 17:01:07 2011
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2008-2010 the EasyAnt project
+ *
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * 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 org.apache.easyant.tasks.menu;
+
+import org.apache.easyant.core.menu.MenuGenerator;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+import java.io.IOException;
+
+/**
+ * This {@link Task} is used to register a new MenuGenerator to a given context.
+ */
+public class RegisterMenuGeneratorTask extends AbstractMenuGeneratorTask {
+
+ /**
+ * Lists built-in menu generator types, which can be specified with a short name rather
+ * than full classname.
+ */
+ public static enum BuiltinType {
+ xooki("org.apache.easyant.menu.XookiMenuGenerator");
+
+ private String generator;
+ private BuiltinType(String generator) {
+ this.generator = generator;
+ }
+
+ public String getGeneratorClassName() {
+ return generator;
+ }
+ }
+
+ private String className;
+ private BuiltinType type;
+ private Path classpath;
+
+ @Override
+ public void execute() throws BuildException {
+ if (getClassName() == null) {
+ throw new BuildException("either className or type argument is required !");
+ }
+
+ MenuGenerator menuGenerator = (MenuGenerator) ClasspathUtils.newInstance(getClassName(), getClassLoader(), MenuGenerator.class);
+ getMenuGeneratorForContext(getContext()).addMenuGenerator(menuGenerator);
+ }
+
+ /**
+ * Get the classname to register
+ * @return a classname
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Set the classname to register
+ * @param className a classname
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public BuiltinType getType() {
+ return type;
+ }
+
+ /**
+ * Set a builtin type to use, as an alternative to {@link #setClassName(String)}.
+ */
+ public void setType(BuiltinType type) {
+ this.type = type;
+ if (type != null) {
+ setClassName(type.getGeneratorClassName());
+ }
+ }
+
+ protected AntClassLoader getClassLoader() {
+ // defining a new specialized classloader and setting it as the thread
+ // context classloader
+ AntClassLoader loader = null;
+ if (classpath != null) {
+ loader = new AntClassLoader(this.getClass().getClassLoader(),
+ getProject(), classpath, false);
+ } else {
+ loader = new AntClassLoader(this.getClass().getClassLoader(),
+ false);
+ }
+ loader.setThreadContextLoader();
+ return loader;
+ }
+
+ /**
+ * Get the classpath used to locate the specified classname
+ * @return a classpath
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+
+ /**
+ * The the classpath used to locate the specified classname
+ *
+ * @param classpath
+ */
+ public void setClasspath(Path classpath) {
+ createClasspath().append(classpath);
+ }
+
+ /**
+ * Classpath to use, by reference, when compiling the rulebase
+ *
+ * @param a reference to an existing classpath
+ */
+ public void setClasspathref(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Adds a path to the classpath.
+ *
+ * @return created classpath
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+}
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/RegisterMenuGeneratorTask.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java (added)
+++ incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java Thu Feb 17 17:01:07 2011
@@ -0,0 +1,45 @@
+package org.apache.easyant.tasks.menu;
+
+import org.apache.easyant.core.menu.MenuGenerator;
+import org.apache.tools.ant.BuildException;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Create a new menu using any registered generators.
+ */
+public class StartMenuTask extends AbstractMenuGeneratorTask {
+
+ private String file;
+
+ @Override
+ public void execute() throws BuildException {
+ if (getFile() == null) {
+ throw new BuildException("file argument is required !");
+ }
+
+ //TODO: this isn't quite right. we shouldn't be passing the same file argument to every generator.
+ List<MenuGenerator> generators = getMenuGeneratorForContext(getContext()).getMenuGenerators();
+ for (MenuGenerator generator : generators) {
+ try {
+ generator.startMenu(getContext(), getFile());
+ } catch (IOException ioe) {
+ throw new BuildException("Error writing menu file " + getFile() + ": " + ioe.getMessage(), ioe);
+ }
+ }
+ }
+
+ /**
+ * Get the file associated to this generator
+ * @return a file
+ */
+ public String getFile() {
+ return file;
+ }
+
+ public void setFile(String file) {
+ this.file = file;
+ }
+
+}
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/tasks/menu/StartMenuTask.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/easyant/core/trunk/src/main/patches/ant-697121-easyant-patch.diff
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/patches/ant-697121-easyant-patch.diff?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/patches/ant-697121-easyant-patch.diff (added)
+++ incubator/easyant/core/trunk/src/main/patches/ant-697121-easyant-patch.diff Thu Feb 17 17:01:07 2011
@@ -0,0 +1,461 @@
+Index: src/main/org/apache/tools/ant/helper/AntXMLContext.java
+===================================================================
+--- src/main/org/apache/tools/ant/helper/AntXMLContext.java (révision 697121)
++++ src/main/org/apache/tools/ant/helper/AntXMLContext.java (copie de travail)
+@@ -95,6 +95,9 @@
+
+ /** Keeps track of targets in files */
+ private Map currentTargets = null;
++
++ /** The prefix to use in import 'use' mode */
++ private String usePrefix = null;
+
+ /**
+ * constructor
+@@ -362,6 +365,24 @@
+ this.currentTargets = currentTargets;
+ }
+
++ /**
++ * Get the prefix to use in import 'use' mode.
++ *
++ * @return the prefix to use in import 'use' mode, <code>null</code> if we
++ * are not parsing file in import 'use' mode.
++ */
++ public String getUsePrefix() {
++ return usePrefix;
++ }
++
++ /**
++ * Set the prefix to use in import 'use' mode.
++ *
++ * @param usePrefix the prefix to use in import 'use' mode.
++ */
++ public void setUsePrefix(String usePrefix) {
++ this.usePrefix = usePrefix;
++ }
+ }
+
+
+Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+===================================================================
+--- src/main/org/apache/tools/ant/helper/ProjectHelper2.java (révision 697121)
++++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java (copie de travail)
+@@ -47,6 +47,7 @@
+ import java.util.Hashtable;
+ import java.util.Map;
+ import java.util.Stack;
++import java.util.StringTokenizer;
+
+ /**
+ * Sax2 based project reader
+@@ -139,6 +140,7 @@
+ context = new AntXMLContext(project);
+ project.addReference(REFID_CONTEXT, context);
+ project.addReference(REFID_TARGETS, context.getTargets());
++ setContext(context);
+ }
+ if (getImportStack().size() > 1) {
+ // we are in an imported file.
+@@ -727,6 +729,16 @@
+ MagicNames.ANT_FILE + "." + context.getCurrentProjectName(), context
+ .getBuildFile().toString());
+ }
++ String usePrefix = context.getUsePrefix();
++ if ("${ant.project.name}".equals(usePrefix)) {
++ // the use prefix to use is the default one: the current project name
++ context.setUsePrefix(usePrefix = context.getCurrentProjectName());
++ }
++ if (usePrefix != null) {
++ project.log("importing project in 'use' mode: "
++ + "all targets will be prefixed with '" + usePrefix +"'",
++ Project.MSG_VERBOSE);
++ }
+ if (context.isIgnoringProjectTag()) {
+ // no further processing
+ return;
+@@ -773,7 +785,8 @@
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+- return name.equals("target") && (uri.equals("") || uri.equals(ANT_CORE_URI))
++ return (name.equals("target") || name.equals("phase"))
++ && (uri.equals("") || uri.equals(ANT_CORE_URI))
+ ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
+ }
+ }
+@@ -807,12 +820,15 @@
+ AntXMLContext context) throws SAXParseException {
+ String name = null;
+ String depends = "";
++ String phase = "";
+
+ Project project = context.getProject();
+ Target target = new Target();
+ target.setProject(project);
+ target.setLocation(new Location(context.getLocator()));
+ context.addTarget(target);
++
++ target.setType(tag);
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attrUri = attrs.getURI(i);
+@@ -829,6 +845,8 @@
+ }
+ } else if (key.equals("depends")) {
+ depends = value;
++ } else if (key.equals("phase")) {
++ phase = value;
+ } else if (key.equals("if")) {
+ target.setIf(value);
+ } else if (key.equals("unless")) {
+@@ -839,6 +857,8 @@
+ }
+ } else if (key.equals("description")) {
+ target.setDescription(value);
++ } else if (key.equals("type")) {
++ target.setType(value);
+ } else {
+ throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
+ .getLocator());
+@@ -849,6 +869,18 @@
+ throw new SAXParseException("target element appears without a name attribute",
+ context.getLocator());
+ }
++
++ boolean isPhase = "phase".equals(target.getType());
++
++ String targetPrefix = isPhase ? null : context.getUsePrefix();
++
++ // check if we should prefix the target name
++ if (targetPrefix != null) {
++ project.log("import 'use' mode: prefixing target '" + name + "' with '"
++ + targetPrefix + "'", Project.MSG_DEBUG);
++
++ name = targetPrefix + name;
++ }
+
+ // Check if this target is in the current build file
+ if (context.getCurrentTargets().get(name) != null) {
+@@ -867,10 +899,93 @@
+ usedTarget = true;
+ }
+ if (depends.length() > 0) {
+- target.setDepends(depends);
++ if (targetPrefix != null) {
++ // parse depends to add prefix to all dependencies
++ // the parsing logic is copied from Target#setDepends(String), which is
++ // not a good thing, but I don't want to make Target 'use' mode aware.
++ // We could move the parsing logic in all cases over here if it wasn't part of
++ // Target public API.
++ StringTokenizer tok =
++ new StringTokenizer(depends, ",", true);
++ while (tok.hasMoreTokens()) {
++ String token = tok.nextToken().trim();
++
++ // Make sure the dependency is not empty string
++ if ("".equals(token) || ",".equals(token)) {
++ throw new BuildException(
++ "Syntax Error: depends " + "attribute of target \""
++ + name + "\" has an empty string as dependency.");
++ }
++
++ Target t = (Target) project.getTargets().get(token);
++ if (t != null && "phase".equals(t.getType())) {
++ target.addDependency(token);
++ } else {
++ target.addDependency(targetPrefix + token);
++ }
++
++ // Make sure that depends attribute does not
++ // end in a ,
++ if (tok.hasMoreTokens()) {
++ token = tok.nextToken();
++ if (!tok.hasMoreTokens() || !",".equals(token)) {
++ throw new BuildException("Syntax Error: Depend "
++ + "attribute for target \"" + name
++ + "\" ends with a , character");
++ }
++ }
++ }
++ } else {
++ target.setDepends(depends);
++ }
+ }
++ if (phase.length() > 0) {
++ if (isPhase) {
++ throw new SAXParseException(
++ "phase not allowed on phase", context.getLocator());
++ }
++ StringTokenizer tok =
++ new StringTokenizer(phase, ",", true);
++ while (tok.hasMoreTokens()) {
++ String token = tok.nextToken().trim();
++
++ // Make sure the dependency is not empty string
++ if ("".equals(token) || ",".equals(token)) {
++ throw new BuildException(
++ "Syntax Error: phase " + "attribute of target \""
++ + name + "\" has an empty string as phase.");
++ }
++
++ Target p = (Target) projectTargets.get(token);
++ if (p == null) {
++ throw new BuildException(
++ "Syntax Error: unknown phase \""
++ + token + "\" referenced by \"" + name + "\".");
++ } else if (!"phase".equals(p.getType())) {
++ throw new BuildException(
++ "Syntax Error: phase \""
++ + token + "\" referenced by \"" + name
++ + "\" is not a phase.");
++ } else {
++ p.addDependency(name);
++ }
++
++ // Make sure that phase attribute does not
++ // end in a ,
++ if (tok.hasMoreTokens()) {
++ token = tok.nextToken();
++ if (!tok.hasMoreTokens() || !",".equals(token)) {
++ throw new BuildException("Syntax Error: Phase "
++ + "attribute for target \"" + name
++ + "\" ends with a , character");
++ }
++ }
++ }
++ }
++
+ if (context.isIgnoringProjectTag() && context.getCurrentProjectName() != null
+- && context.getCurrentProjectName().length() != 0) {
++ && context.getCurrentProjectName().length() != 0
++ && !isPhase) {
+ // In an impored file (and not completely
+ // ignoring the project tag)
+ String newName = context.getCurrentProjectName() + "." + name;
+Index: src/main/org/apache/tools/ant/ProjectHelper.java
+===================================================================
+--- src/main/org/apache/tools/ant/ProjectHelper.java (révision 697121)
++++ src/main/org/apache/tools/ant/ProjectHelper.java (copie de travail)
+@@ -28,6 +28,7 @@
+
+ import org.xml.sax.AttributeList;
+
++import org.apache.tools.ant.helper.AntXMLContext;
+ import org.apache.tools.ant.helper.ProjectHelper2;
+ import org.apache.tools.ant.util.LoaderUtils;
+
+@@ -129,6 +130,20 @@
+ public Vector getImportStack() {
+ return importStack;
+ }
++
++ private AntXMLContext context = null;
++
++ /**
++ * Returns the current parsing context
++ * @return the current parsing context
++ */
++ public AntXMLContext getContext() {
++ return context;
++ }
++
++ protected void setContext(AntXMLContext context) {
++ this.context = context;
++ }
+
+ // -------------------- Parse method --------------------
+ /**
+Index: src/main/org/apache/tools/ant/taskdefs/ImportTask.java
+===================================================================
+--- src/main/org/apache/tools/ant/taskdefs/ImportTask.java (révision 697121)
++++ src/main/org/apache/tools/ant/taskdefs/ImportTask.java (copie de travail)
+@@ -18,15 +18,16 @@
+
+ package org.apache.tools.ant.taskdefs;
+
++import java.io.File;
++import java.util.Vector;
++
+ import org.apache.tools.ant.BuildException;
++import org.apache.tools.ant.Project;
+ import org.apache.tools.ant.ProjectHelper;
+-import org.apache.tools.ant.Project;
+ import org.apache.tools.ant.Task;
++import org.apache.tools.ant.helper.AntXMLContext;
+ import org.apache.tools.ant.util.FileUtils;
+
+-import java.io.File;
+-import java.util.Vector;
+-
+ /**
+ * Task to import another build file into the current project.
+ * <p>
+@@ -55,6 +56,9 @@
+ public class ImportTask extends Task {
+ private String file;
+ private boolean optional;
++ private String mode = "extends";
++ private String as;
++
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+@@ -79,6 +83,22 @@
+ }
+
+ /**
++ * The import mode to use. It can be either 'use' or 'extends'
++ * @param mode the import mode to use
++ */
++ public void setMode(String mode) {
++ this.mode = mode;
++ }
++
++ /**
++ * The prefix to use when importing in 'use' mode.
++ * @param as the prefix for 'use' mode
++ */
++ public void setAs(String as) {
++ this.as = as;
++ }
++
++ /**
+ * This relies on the task order model.
+ *
+ */
+@@ -134,19 +154,45 @@
+ throw new BuildException(message);
+ }
+ }
+-
+- if (importStack.contains(importedFile)) {
++ //here we suppose that using import "as" mode you know what you do
++ if ((!"use".equals(mode)) && importStack.contains(importedFile)) {
+ getProject().log(
+ "Skipped already imported file:\n "
+ + importedFile + "\n", Project.MSG_VERBOSE);
+ return;
+ }
+
++ AntXMLContext context = helper.getContext();
++ String oldUsePrefix = null;
+ try {
++ if ("use".equals(mode)) {
++ if (context == null) {
++ throw new IllegalStateException("null context while calling import in use mode."
++ + " The ProjectHelper implementation you use may not support 'use' mode");
++ }
++ oldUsePrefix = context.getUsePrefix();
++ if (as != null) {
++ if (oldUsePrefix != null) {
++ context.setUsePrefix(oldUsePrefix + as);
++ } else {
++ context.setUsePrefix(as);
++ }
++ } else {
++ if (oldUsePrefix != null) {
++ context.setUsePrefix(oldUsePrefix + "${ant.project.name}");
++ } else {
++ context.setUsePrefix("${ant.project.name}");
++ }
++ }
++ }
+ helper.parse(getProject(), importedFile);
+ } catch (BuildException ex) {
+ throw ProjectHelper.addLocationToBuildException(
+ ex, getLocation());
++ } finally {
++ if ("use".equals(mode) && context != null) {
++ context.setUsePrefix(oldUsePrefix);
++ }
+ }
+ }
+
+Index: src/main/org/apache/tools/ant/Main.java
+===================================================================
+--- src/main/org/apache/tools/ant/Main.java (révision 697121)
++++ src/main/org/apache/tools/ant/Main.java (copie de travail)
+@@ -1044,6 +1044,8 @@
+ Vector topNames = new Vector();
+ Vector topDescriptions = new Vector();
+ Vector subNames = new Vector();
++ Vector phases = new Vector();
++ Vector phasesDescriptions = new Vector();
+
+ for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
+ currentTarget = (Target) i.next();
+@@ -1057,17 +1059,28 @@
+ int pos = findTargetPosition(subNames, targetName);
+ subNames.insertElementAt(targetName, pos);
+ } else {
+- int pos = findTargetPosition(topNames, targetName);
+- topNames.insertElementAt(targetName, pos);
+- topDescriptions.insertElementAt(targetDescription, pos);
+- if (targetName.length() > maxLength) {
+- maxLength = targetName.length();
+- }
++ if (currentTarget.getType().equals("phase")) {
++ int pos = findTargetPosition(phases, targetName);
++ phases.insertElementAt(targetName, pos);
++ phasesDescriptions.insertElementAt(targetDescription, pos);
++ } else {
++ int pos = findTargetPosition(topNames, targetName);
++ topNames.insertElementAt(targetName, pos);
++ topDescriptions.insertElementAt(targetDescription, pos);
++
++ }
++ if (targetName.length() > maxLength) {
++ maxLength = targetName.length();
++ }
++
+ }
+ }
+
++ printTargets(project, phases,phasesDescriptions,"Main phases:",maxLength);
+ printTargets(project, topNames, topDescriptions, "Main targets:",
+ maxLength);
++
++
+ //if there were no main targets, we list all subtargets
+ //as it means nothing has a description
+ if (topNames.size() == 0) {
+Index: src/main/org/apache/tools/ant/Target.java
+===================================================================
+--- src/main/org/apache/tools/ant/Target.java (révision 697121)
++++ src/main/org/apache/tools/ant/Target.java (copie de travail)
+@@ -56,6 +56,9 @@
+
+ /** Description of this target, if any. */
+ private String description = null;
++
++ /** The type of target ("target" or "phase") */
++ private String type = "target";
+
+ /** Default constructor. */
+ public Target() {
+@@ -172,6 +175,24 @@
+ public String getName() {
+ return name;
+ }
++
++ /**
++ * Returns the type of this target.
++ *
++ * @return the type of this target
++ */
++ public String getType() {
++ return type;
++ }
++
++ /**
++ * Sets the type of this target.
++ *
++ * @param type the new type of this target
++ */
++ public void setType(String type) {
++ this.type = type;
++ }
+
+ /**
+ * Adds a task to this target.
Added: incubator/easyant/core/trunk/src/main/patches/ant-713373-easyant-patch.diff
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/patches/ant-713373-easyant-patch.diff?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/patches/ant-713373-easyant-patch.diff (added)
+++ incubator/easyant/core/trunk/src/main/patches/ant-713373-easyant-patch.diff Thu Feb 17 17:01:07 2011
@@ -0,0 +1,211 @@
+Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+===================================================================
+--- src/main/org/apache/tools/ant/helper/ProjectHelper2.java (révision 713424)
++++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java (copie de travail)
+@@ -769,7 +769,7 @@
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+- return name.equals("target") && (uri.equals("") || uri.equals(ANT_CORE_URI))
++ return (name.equals("target") || name.equals("phase")) && (uri.equals("") || uri.equals(ANT_CORE_URI))
+ ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
+ }
+ }
+@@ -803,12 +803,15 @@
+ AntXMLContext context) throws SAXParseException {
+ String name = null;
+ String depends = "";
++ String phase = "";
+
+ Project project = context.getProject();
+ Target target = new Target();
+ target.setProject(project);
+ target.setLocation(new Location(context.getLocator()));
+ context.addTarget(target);
++
++ target.setType(tag);
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attrUri = attrs.getURI(i);
+@@ -825,6 +828,8 @@
+ }
+ } else if (key.equals("depends")) {
+ depends = value;
++ } else if (key.equals("phase")) {
++ phase = value;
+ } else if (key.equals("if")) {
+ target.setIf(value);
+ } else if (key.equals("unless")) {
+@@ -835,12 +840,17 @@
+ }
+ } else if (key.equals("description")) {
+ target.setDescription(value);
++ } else if (key.equals("type")) {
++ target.setType(value);
++
+ } else {
+ throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
+ .getLocator());
+ }
+ }
+-
++
++ boolean isPhase = "phase".equals(target.getType());
++
+ if (name == null) {
+ throw new SAXParseException("target element appears without a name attribute",
+ context.getLocator());
+@@ -849,9 +859,10 @@
+ String prefix = null;
+ boolean isInIncludeMode =
+ context.isIgnoringProjectTag() && isInIncludeMode();
++
+ String sep = getCurrentPrefixSeparator();
+
+- if (isInIncludeMode) {
++ if (isInIncludeMode && !isPhase) {
+ prefix = getTargetPrefix(context);
+ if (prefix == null) {
+ throw new BuildException("can't include build file "
+@@ -888,12 +899,40 @@
+ for (Iterator iter =
+ Target.parseDepends(depends, name).iterator();
+ iter.hasNext(); ) {
+- target.addDependency(prefix + sep + iter.next());
++ String token = (String) iter.next();
++ Target t = (Target) project.getTargets().get(token);
++ if (t != null && "phase".equals(t.getType())) {
++ target.addDependency(token);
++ } else {
++ target.addDependency(prefix + sep + token);
++ }
+ }
+ }
+ }
++ if (phase.length() > 0) {
++ if (isPhase) {
++ throw new SAXParseException("phase not allowed on phase",
++ context.getLocator());
++ }
++ for (Iterator iter = Target.parseDepends(phase, name)
++ .iterator(); iter.hasNext();) {
++ String token = (String) iter.next();
++ Target p = (Target) projectTargets.get(token);
++ if (p == null) {
++ throw new BuildException(
++ "Syntax Error: unknown phase \"" + token
++ + "\" referenced by \"" + name + "\".");
++ } else if (!"phase".equals(p.getType())) {
++ throw new BuildException("Syntax Error: phase \""
++ + token + "\" referenced by \"" + name
++ + "\" is not a phase.");
++ } else {
++ p.addDependency(name);
++ }
++ }
++ }
+ if (!isInIncludeMode && context.isIgnoringProjectTag()
+- && (prefix = getTargetPrefix(context)) != null) {
++ && (prefix = getTargetPrefix(context)) != null && !isPhase) {
+ // In an imported file (and not completely
+ // ignoring the project tag or having a preconfigured prefix)
+ String newName = prefix + sep + name;
+@@ -906,9 +945,11 @@
+
+ private String getTargetPrefix(AntXMLContext context) {
+ String configuredValue = getCurrentTargetPrefix();
++ /*
+ if (configuredValue != null && configuredValue.length() == 0) {
+ configuredValue = null;
+ }
++ */
+ if (configuredValue != null) {
+ return configuredValue;
+ }
+Index: src/main/org/apache/tools/ant/Main.java
+===================================================================
+--- src/main/org/apache/tools/ant/Main.java (révision 713424)
++++ src/main/org/apache/tools/ant/Main.java (copie de travail)
+@@ -1058,6 +1058,8 @@
+ Vector topNames = new Vector();
+ Vector topDescriptions = new Vector();
+ Vector subNames = new Vector();
++ Vector phases = new Vector();
++ Vector phasesDescriptions = new Vector();
+
+ for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
+ currentTarget = (Target) i.next();
+@@ -1071,17 +1073,28 @@
+ int pos = findTargetPosition(subNames, targetName);
+ subNames.insertElementAt(targetName, pos);
+ } else {
+- int pos = findTargetPosition(topNames, targetName);
+- topNames.insertElementAt(targetName, pos);
+- topDescriptions.insertElementAt(targetDescription, pos);
+- if (targetName.length() > maxLength) {
+- maxLength = targetName.length();
+- }
++ if (currentTarget.getType().equals("phase")) {
++ int pos = findTargetPosition(phases, targetName);
++ phases.insertElementAt(targetName, pos);
++ phasesDescriptions.insertElementAt(targetDescription, pos);
++ } else {
++ int pos = findTargetPosition(topNames, targetName);
++ topNames.insertElementAt(targetName, pos);
++ topDescriptions.insertElementAt(targetDescription, pos);
++
++ }
++ if (targetName.length() > maxLength) {
++ maxLength = targetName.length();
++ }
++
+ }
+ }
+
++ printTargets(project, phases,phasesDescriptions,"Main phases:",maxLength);
+ printTargets(project, topNames, topDescriptions, "Main targets:",
+ maxLength);
++
++
+ //if there were no main targets, we list all subtargets
+ //as it means nothing has a description
+ if (topNames.size() == 0) {
+Index: src/main/org/apache/tools/ant/Target.java
+===================================================================
+--- src/main/org/apache/tools/ant/Target.java (révision 713424)
++++ src/main/org/apache/tools/ant/Target.java (copie de travail)
+@@ -55,6 +55,9 @@
+
+ /** Description of this target, if any. */
+ private String description = null;
++
++ /** The type of target ("target" or "phase") */
++ private String type = "target";
+
+ /** Default constructor. */
+ public Target() {
+@@ -186,6 +189,24 @@
+ public String getName() {
+ return name;
+ }
++
++ /**
++ * Returns the type of this target.
++ *
++ * @return the type of this target
++ */
++ public String getType() {
++ return type;
++ }
++
++ /**
++ * Sets the type of this target.
++ *
++ * @param type the new type of this target
++ */
++ public void setType(String type) {
++ this.type = type;
++ }
+
+ /**
+ * Adds a task to this target.
Added: incubator/easyant/core/trunk/src/main/patches/ant-713748-easyant-patch.diff
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/patches/ant-713748-easyant-patch.diff?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/patches/ant-713748-easyant-patch.diff (added)
+++ incubator/easyant/core/trunk/src/main/patches/ant-713748-easyant-patch.diff Thu Feb 17 17:01:07 2011
@@ -0,0 +1,193 @@
+Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+===================================================================
+--- src/main/org/apache/tools/ant/helper/ProjectHelper2.java (révision 713748)
++++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java (copie de travail)
+@@ -777,7 +777,7 @@
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+- return name.equals("target") && (uri.equals("") || uri.equals(ANT_CORE_URI))
++ return (name.equals("target") || name.equals("phase")) && (uri.equals("") || uri.equals(ANT_CORE_URI))
+ ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
+ }
+ }
+@@ -811,12 +811,15 @@
+ AntXMLContext context) throws SAXParseException {
+ String name = null;
+ String depends = "";
++ String phase = "";
+
+ Project project = context.getProject();
+ Target target = new Target();
+ target.setProject(project);
+ target.setLocation(new Location(context.getLocator()));
+ context.addTarget(target);
++
++ target.setType(tag);
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attrUri = attrs.getURI(i);
+@@ -833,6 +836,8 @@
+ }
+ } else if (key.equals("depends")) {
+ depends = value;
++ } else if (key.equals("phase")) {
++ phase = value;
+ } else if (key.equals("if")) {
+ target.setIf(value);
+ } else if (key.equals("unless")) {
+@@ -843,11 +848,15 @@
+ }
+ } else if (key.equals("description")) {
+ target.setDescription(value);
++ } else if (key.equals("type")) {
++ target.setType(value);
+ } else {
+ throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
+ .getLocator());
+ }
+ }
++
++ boolean isPhase = "phase".equals(target.getType());
+
+ if (name == null) {
+ throw new SAXParseException("target element appears without a name attribute",
+@@ -859,7 +868,7 @@
+ context.isIgnoringProjectTag() && isInIncludeMode();
+ String sep = getCurrentPrefixSeparator();
+
+- if (isInIncludeMode) {
++ if (isInIncludeMode && !isPhase) {
+ prefix = getTargetPrefix(context);
+ if (prefix == null) {
+ throw new BuildException("can't include build file "
+@@ -896,12 +905,40 @@
+ for (Iterator iter =
+ Target.parseDepends(depends, name).iterator();
+ iter.hasNext(); ) {
+- target.addDependency(prefix + sep + iter.next());
++ String token = (String) iter.next();
++ Target t = (Target) project.getTargets().get(token);
++ if (t != null && "phase".equals(t.getType())) {
++ target.addDependency(token);
++ } else {
++ target.addDependency(prefix + sep + token);
++ }
+ }
+ }
+ }
++ if (phase.length() > 0) {
++ if (isPhase) {
++ throw new SAXParseException("phase not allowed on phase",
++ context.getLocator());
++ }
++ for (Iterator iter = Target.parseDepends(phase, name)
++ .iterator(); iter.hasNext();) {
++ String token = (String) iter.next();
++ Target p = (Target) projectTargets.get(token);
++ if (p == null) {
++ throw new BuildException(
++ "Syntax Error: unknown phase \"" + token
++ + "\" referenced by \"" + name + "\".");
++ } else if (!"phase".equals(p.getType())) {
++ throw new BuildException("Syntax Error: phase \""
++ + token + "\" referenced by \"" + name
++ + "\" is not a phase.");
++ } else {
++ p.addDependency(name);
++ }
++ }
++ }
+ if (!isInIncludeMode && context.isIgnoringProjectTag()
+- && (prefix = getTargetPrefix(context)) != null) {
++ && (prefix = getTargetPrefix(context)) != null && !isPhase) {
+ // In an imported file (and not completely
+ // ignoring the project tag or having a preconfigured prefix)
+ String newName = prefix + sep + name;
+Index: src/main/org/apache/tools/ant/Main.java
+===================================================================
+--- src/main/org/apache/tools/ant/Main.java (révision 713748)
++++ src/main/org/apache/tools/ant/Main.java (copie de travail)
+@@ -1058,6 +1058,8 @@
+ Vector topNames = new Vector();
+ Vector topDescriptions = new Vector();
+ Vector subNames = new Vector();
++ Vector phases = new Vector();
++ Vector phasesDescriptions = new Vector();
+
+ for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
+ currentTarget = (Target) i.next();
+@@ -1071,17 +1073,28 @@
+ int pos = findTargetPosition(subNames, targetName);
+ subNames.insertElementAt(targetName, pos);
+ } else {
+- int pos = findTargetPosition(topNames, targetName);
+- topNames.insertElementAt(targetName, pos);
+- topDescriptions.insertElementAt(targetDescription, pos);
+- if (targetName.length() > maxLength) {
+- maxLength = targetName.length();
+- }
++ if (currentTarget.getType().equals("phase")) {
++ int pos = findTargetPosition(phases, targetName);
++ phases.insertElementAt(targetName, pos);
++ phasesDescriptions.insertElementAt(targetDescription, pos);
++ } else {
++ int pos = findTargetPosition(topNames, targetName);
++ topNames.insertElementAt(targetName, pos);
++ topDescriptions.insertElementAt(targetDescription, pos);
++
++ }
++ if (targetName.length() > maxLength) {
++ maxLength = targetName.length();
++ }
++
+ }
+ }
+
++ printTargets(project, phases,phasesDescriptions,"Main phases:",maxLength);
+ printTargets(project, topNames, topDescriptions, "Main targets:",
+ maxLength);
++
++
+ //if there were no main targets, we list all subtargets
+ //as it means nothing has a description
+ if (topNames.size() == 0) {
+Index: src/main/org/apache/tools/ant/Target.java
+===================================================================
+--- src/main/org/apache/tools/ant/Target.java (révision 713748)
++++ src/main/org/apache/tools/ant/Target.java (copie de travail)
+@@ -55,6 +55,9 @@
+
+ /** Description of this target, if any. */
+ private String description = null;
++
++ /** The type of target ("target" or "phase") */
++ private String type = "target";
+
+ /** Default constructor. */
+ public Target() {
+@@ -186,6 +189,24 @@
+ public String getName() {
+ return name;
+ }
++
++ /**
++ * Returns the type of this target.
++ *
++ * @return the type of this target
++ */
++ public String getType() {
++ return type;
++ }
++
++ /**
++ * Sets the type of this target.
++ *
++ * @param type the new type of this target
++ */
++ public void setType(String type) {
++ this.type = type;
++ }
+
+ /**
+ * Adds a task to this target.
Added: incubator/easyant/core/trunk/src/main/patches/extendsIvyFile-ivy-r709181.patch
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/patches/extendsIvyFile-ivy-r709181.patch?rev=1071697&view=auto
==============================================================================
--- incubator/easyant/core/trunk/src/main/patches/extendsIvyFile-ivy-r709181.patch (added)
+++ incubator/easyant/core/trunk/src/main/patches/extendsIvyFile-ivy-r709181.patch Thu Feb 17 17:01:07 2011
@@ -0,0 +1,220 @@
+Index: src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
+===================================================================
+--- src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (révision 709181)
++++ src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (copie de travail)
+@@ -40,6 +40,7 @@
+ import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
+ import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
+ import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
++import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+ import org.apache.ivy.core.module.descriptor.ExcludeRule;
+ import org.apache.ivy.core.module.descriptor.IncludeRule;
+ import org.apache.ivy.core.module.descriptor.License;
+@@ -49,15 +50,21 @@
+ import org.apache.ivy.core.module.id.ArtifactId;
+ import org.apache.ivy.core.module.id.ModuleId;
+ import org.apache.ivy.core.module.id.ModuleRevisionId;
++import org.apache.ivy.core.resolve.ResolveData;
++import org.apache.ivy.core.resolve.ResolveEngine;
++import org.apache.ivy.core.resolve.ResolveOptions;
++import org.apache.ivy.core.resolve.ResolvedModuleRevision;
+ import org.apache.ivy.plugins.conflict.ConflictManager;
+ import org.apache.ivy.plugins.conflict.FixedConflictManager;
+ import org.apache.ivy.plugins.matcher.PatternMatcher;
+ import org.apache.ivy.plugins.namespace.Namespace;
+ import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
+ import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
++import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
+ import org.apache.ivy.plugins.parser.ParserSettings;
+ import org.apache.ivy.plugins.repository.Resource;
+ import org.apache.ivy.plugins.repository.url.URLResource;
++import org.apache.ivy.plugins.resolver.DependencyResolver;
+ import org.apache.ivy.util.Message;
+ import org.apache.ivy.util.XMLHelper;
+ import org.apache.ivy.util.extendable.ExtendableItemHelper;
+@@ -211,6 +218,7 @@
+ private StringBuffer buffer;
+ private String descriptorVersion;
+ private String[] publicationsDefaultConf;
++
+
+ public Parser(ModuleDescriptorParser parser, ParserSettings ivySettings) {
+ super(parser);
+@@ -276,6 +284,8 @@
+ ivyModuleStarted(attributes);
+ } else if ("info".equals(qName)) {
+ infoStarted(attributes);
++ } else if (state == State.INFO && "extends".equals(qName)) {
++ extendsStarted(attributes);
+ } else if (state == State.INFO && "license".equals(qName)) {
+ getMd().addLicense(new License(settings.substitute(attributes.getValue("name")),
+ settings.substitute(attributes.getValue("url"))));
+@@ -340,7 +350,148 @@
+ throw sax;
+ }
+ }
++
++ protected String getDefaultParentLocation() {
++ return "../ivy.xml";
++ }
++
++ protected void extendsStarted(Attributes attributes) throws ParseException {
++ String parentOrganisation = attributes.getValue("organisation");
++ String parentModule = attributes.getValue("name");
++ String parentRevision = attributes.getValue("revision");
++ String location = attributes.getValue("location") != null ? attributes
++ .getValue("location") : getDefaultParentLocation();
++ ModuleDescriptor parent = null;
+
++ String extendType = attributes.getValue("extendType") != null ? attributes.getValue(
++ "extendType").toLowerCase() : "all";
++
++ List/* <String> */extendTypes = Arrays.asList(extendType.split(","));
++
++
++ try {
++ Message.debug("Trying to parse included ivy file :" + location);
++ parent = parseOtherIvyFileOnFileSystem(location);
++ } catch (ParseException e) {
++ Message.warn("Unable to parse included ivy file : " + location);
++ } catch (IOException e) {
++ Message.warn("Unable to parse included ivy file : " + location);
++ }
++
++ // if the included ivy file is not found on file system, tries to resolve using
++ // repositories
++ if (parent == null) {
++ try {
++ Message
++ .debug("Trying to parse included ivy file by asking repository for module :"
++ + parentOrganisation
++ + "#"
++ + parentModule
++ + ";"
++ + parentRevision);
++ parent = parseOtherIvyFile(parentOrganisation, parentModule, parentRevision);
++ } catch (ParseException e) {
++ Message.warn("Unable to parse included ivy file for " + parentOrganisation
++ + "#" + parentModule + ";" + parentRevision);
++ }
++ }
++
++ if (parent == null) {
++ throw new ParseException("Unable to parse included ivy file for "
++ + parentOrganisation + "#" + parentModule + ";" + parentRevision, 0);
++ }
++ mergeWithOtherModuleDescriptor(extendTypes,parent);
++ }
++
++ protected void mergeWithOtherModuleDescriptor(List/*<String>*/ extendTypes,ModuleDescriptor parent) {
++ if (extendTypes.contains("all")) {
++ mergeAll(parent);
++ } else {
++ if (extendTypes.contains("configurations")) {
++ mergeConfigurations(parent.getConfigurations());
++ }
++
++ if (extendTypes.contains("dependencies")) {
++ mergeDependencies(parent.getDependencies());
++ }
++
++ if (extendTypes.contains("description")) {
++ mergeDescription(parent.getDescription());
++ }
++ }
++
++ }
++
++ protected void mergeAll(ModuleDescriptor parent) {
++ mergeConfigurations(parent.getConfigurations());
++ mergeDependencies(parent.getDependencies());
++ mergeDescription(parent.getDescription());
++ }
++
++ protected void mergeConfigurations(Configuration[] configurations) {
++ for (int i = 0; i < configurations.length; i++) {
++ Configuration configuration = configurations[i];
++ Message.debug("Merging configuration with: " + configuration.getName());
++ // TODO: Here we need to merge configuration
++ getMd().addConfiguration(configuration);
++ }
++ }
++
++ protected void mergeDependencies(DependencyDescriptor[] dependencies) {
++ for (int i = 0; i < dependencies.length; i++) {
++ DependencyDescriptor dependencyDescriptor = dependencies[i];
++ Message.debug("Merging dependency with: "
++ + dependencyDescriptor.getDependencyRevisionId().toString());
++ // TODO: Here we need to merge dependencies
++ getMd().addDependency(dependencyDescriptor);
++ }
++ }
++
++ protected void mergeDescription(String description) {
++ if (getMd().getDescription() == null)
++ getMd().setDescription(description);
++ }
++
++ protected ModuleDescriptor parseOtherIvyFileOnFileSystem(String location)
++ throws ParseException, IOException {
++ URL url = null;
++ ModuleDescriptor parent = null;
++ url = getSettings().getRelativeUrlResolver().getURL(descriptorURL, location);
++ Message.debug("Trying to load included ivy file from " + url.toString());
++ URLResource res = new URLResource(url);
++ ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(
++ res);
++
++ parent = parser.parseDescriptor(getSettings(), url, isValidate());
++ return parent;
++ }
++
++ protected ModuleDescriptor parseOtherIvyFile(String parentOrganisation,
++ String parentModule, String parentRevision) throws ParseException {
++ ModuleId parentModuleId = new ModuleId(parentOrganisation, parentModule);
++ ModuleRevisionId parentMrid = new ModuleRevisionId(parentModuleId, parentRevision);
++ DependencyDescriptor dd = new DefaultDependencyDescriptor(parentMrid, true);
++ ResolveData data = IvyContext.getContext().getResolveData();
++ if (data == null) {
++ ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
++ ResolveOptions options = new ResolveOptions();
++ options.setDownload(false);
++ data = new ResolveData(engine, options);
++ }
++
++ DependencyResolver resolver = getSettings().getResolver(parentMrid);
++ if (resolver == null) {
++ // TODO: Throw exception here?
++ return null;
++ } else {
++ ResolvedModuleRevision otherModule = resolver.getDependency(dd, data);
++ if (otherModule == null)
++ throw new ParseException("Unable to find " + parentMrid.toString(), 0);
++ return otherModule.getDescriptor();
++ }
++
++ }
++
+ protected void publicationsStarted(Attributes attributes) {
+ state = State.PUB;
+ artifactsDeclared = true;
+Index: src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd
+===================================================================
+--- src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd (révision 709181)
++++ src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd (copie de travail)
+@@ -60,6 +60,15 @@
+ <xs:element name="info">
+ <xs:complexType>
+ <xs:sequence>
++ <xs:element name="extends" minOccurs="0" maxOccurs="unbounded">
++ <xs:complexType>
++ <xs:attribute name="organisation" type="xs:string" use="required"/>
++ <xs:attribute name="name" type="xs:string" use="required"/>
++ <xs:attribute name="revision" type="xs:string" use="required"/>
++ <xs:attribute name="location" type="xs:string" />
++ <xs:attribute name="extendType" type="xs:string" />
++ </xs:complexType>
++ </xs:element>
+ <xs:element name="license" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required"/>