You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Ant.java 26 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.File;
  20. import java.io.FileOutputStream;
  21. import java.io.IOException;
  22. import java.io.PrintStream;
  23. import java.lang.reflect.Method;
  24. import java.util.Enumeration;
  25. import java.util.Hashtable;
  26. import java.util.Iterator;
  27. import java.util.Vector;
  28. import java.util.Set;
  29. import java.util.HashSet;
  30. import org.apache.tools.ant.BuildException;
  31. import org.apache.tools.ant.BuildListener;
  32. import org.apache.tools.ant.DefaultLogger;
  33. import org.apache.tools.ant.Project;
  34. import org.apache.tools.ant.ProjectComponent;
  35. import org.apache.tools.ant.ProjectHelper;
  36. import org.apache.tools.ant.Target;
  37. import org.apache.tools.ant.Task;
  38. import org.apache.tools.ant.MagicNames;
  39. import org.apache.tools.ant.Main;
  40. import org.apache.tools.ant.types.PropertySet;
  41. import org.apache.tools.ant.util.FileUtils;
  42. /**
  43. * Build a sub-project.
  44. *
  45. * <pre>
  46. * &lt;target name=&quot;foo&quot; depends=&quot;init&quot;&gt;
  47. * &lt;ant antfile=&quot;build.xml&quot; target=&quot;bar&quot; &gt;
  48. * &lt;property name=&quot;property1&quot; value=&quot;aaaaa&quot; /&gt;
  49. * &lt;property name=&quot;foo&quot; value=&quot;baz&quot; /&gt;
  50. * &lt;/ant&gt;</span>
  51. * &lt;/target&gt;</span>
  52. *
  53. * &lt;target name=&quot;bar&quot; depends=&quot;init&quot;&gt;
  54. * &lt;echo message=&quot;prop is ${property1} ${foo}&quot; /&gt;
  55. * &lt;/target&gt;
  56. * </pre>
  57. *
  58. *
  59. * @since Ant 1.1
  60. *
  61. * @ant.task category="control"
  62. */
  63. public class Ant extends Task {
  64. private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
  65. /** the basedir where is executed the build file */
  66. private File dir = null;
  67. /**
  68. * the build.xml file (can be absolute) in this case dir will be
  69. * ignored
  70. */
  71. private String antFile = null;
  72. /** the output */
  73. private String output = null;
  74. /** should we inherit properties from the parent ? */
  75. private boolean inheritAll = true;
  76. /** should we inherit references from the parent ? */
  77. private boolean inheritRefs = false;
  78. /** the properties to pass to the new project */
  79. private Vector properties = new Vector();
  80. /** the references to pass to the new project */
  81. private Vector references = new Vector();
  82. /** the temporary project created to run the build file */
  83. private Project newProject;
  84. /** The stream to which output is to be written. */
  85. private PrintStream out = null;
  86. /** the sets of properties to pass to the new project */
  87. private Vector propertySets = new Vector();
  88. /** the targets to call on the new project */
  89. private Vector targets = new Vector();
  90. /** whether the target attribute was specified **/
  91. private boolean targetAttributeSet = false;
  92. /**
  93. * simple constructor
  94. */
  95. public Ant() {
  96. //default
  97. }
  98. /**
  99. * create a task bound to its creator
  100. * @param owner owning task
  101. */
  102. public Ant(Task owner) {
  103. bindToOwner(owner);
  104. }
  105. /**
  106. * If true, pass all properties to the new Ant project.
  107. * Defaults to true.
  108. * @param value if true pass all properties to the new Ant project.
  109. */
  110. public void setInheritAll(boolean value) {
  111. inheritAll = value;
  112. }
  113. /**
  114. * If true, pass all references to the new Ant project.
  115. * Defaults to false.
  116. * @param value if true, pass all references to the new Ant project
  117. */
  118. public void setInheritRefs(boolean value) {
  119. inheritRefs = value;
  120. }
  121. /**
  122. * Creates a Project instance for the project to call.
  123. */
  124. public void init() {
  125. newProject = getProject().createSubProject();
  126. newProject.setJavaVersionProperty();
  127. }
  128. /**
  129. * Called in execute or createProperty (via getNewProject())
  130. * if newProject is null.
  131. *
  132. * <p>This can happen if the same instance of this task is run
  133. * twice as newProject is set to null at the end of execute (to
  134. * save memory and help the GC).</p>
  135. * <p>calls init() again</p>
  136. *
  137. */
  138. private void reinit() {
  139. init();
  140. }
  141. /**
  142. * Attaches the build listeners of the current project to the new
  143. * project, configures a possible logfile, transfers task and
  144. * data-type definitions, transfers properties (either all or just
  145. * the ones specified as user properties to the current project,
  146. * depending on inheritall), transfers the input handler.
  147. */
  148. private void initializeProject() {
  149. newProject.setInputHandler(getProject().getInputHandler());
  150. Iterator iter = getBuildListeners();
  151. while (iter.hasNext()) {
  152. newProject.addBuildListener((BuildListener) iter.next());
  153. }
  154. if (output != null) {
  155. File outfile = null;
  156. if (dir != null) {
  157. outfile = FILE_UTILS.resolveFile(dir, output);
  158. } else {
  159. outfile = getProject().resolveFile(output);
  160. }
  161. try {
  162. out = new PrintStream(new FileOutputStream(outfile));
  163. DefaultLogger logger = new DefaultLogger();
  164. logger.setMessageOutputLevel(Project.MSG_INFO);
  165. logger.setOutputPrintStream(out);
  166. logger.setErrorPrintStream(out);
  167. newProject.addBuildListener(logger);
  168. } catch (IOException ex) {
  169. log("Ant: Can't set output to " + output);
  170. }
  171. }
  172. // set user-defined properties
  173. getProject().copyUserProperties(newProject);
  174. if (!inheritAll) {
  175. // set Java built-in properties separately,
  176. // b/c we won't inherit them.
  177. newProject.setSystemProperties();
  178. } else {
  179. // set all properties from calling project
  180. addAlmostAll(getProject().getProperties());
  181. }
  182. Enumeration e = propertySets.elements();
  183. while (e.hasMoreElements()) {
  184. PropertySet ps = (PropertySet) e.nextElement();
  185. addAlmostAll(ps.getProperties());
  186. }
  187. }
  188. /**
  189. * Handles output.
  190. * Send it the the new project if is present, otherwise
  191. * call the super class.
  192. * @param outputToHandle The string output to output.
  193. * @see Task#handleOutput(String)
  194. * @since Ant 1.5
  195. */
  196. public void handleOutput(String outputToHandle) {
  197. if (newProject != null) {
  198. newProject.demuxOutput(outputToHandle, false);
  199. } else {
  200. super.handleOutput(outputToHandle);
  201. }
  202. }
  203. /**
  204. * Handles input.
  205. * Deleate to the created project, if present, otherwise
  206. * call the super class.
  207. * @param buffer the buffer into which data is to be read.
  208. * @param offset the offset into the buffer at which data is stored.
  209. * @param length the amount of data to read.
  210. *
  211. * @return the number of bytes read.
  212. *
  213. * @exception IOException if the data cannot be read.
  214. * @see Task#handleInput(byte[], int, int)
  215. * @since Ant 1.6
  216. */
  217. public int handleInput(byte[] buffer, int offset, int length)
  218. throws IOException {
  219. if (newProject != null) {
  220. return newProject.demuxInput(buffer, offset, length);
  221. }
  222. return super.handleInput(buffer, offset, length);
  223. }
  224. /**
  225. * Handles output.
  226. * Send it the the new project if is present, otherwise
  227. * call the super class.
  228. * @param toFlush The string to output.
  229. * @see Task#handleFlush(String)
  230. * @since Ant 1.5.2
  231. */
  232. public void handleFlush(String toFlush) {
  233. if (newProject != null) {
  234. newProject.demuxFlush(toFlush, false);
  235. } else {
  236. super.handleFlush(toFlush);
  237. }
  238. }
  239. /**
  240. * Handle error output.
  241. * Send it the the new project if is present, otherwise
  242. * call the super class.
  243. * @param errorOutputToHandle The string to output.
  244. *
  245. * @see Task#handleErrorOutput(String)
  246. * @since Ant 1.5
  247. */
  248. public void handleErrorOutput(String errorOutputToHandle) {
  249. if (newProject != null) {
  250. newProject.demuxOutput(errorOutputToHandle, true);
  251. } else {
  252. super.handleErrorOutput(errorOutputToHandle);
  253. }
  254. }
  255. /**
  256. * Handle error output.
  257. * Send it the the new project if is present, otherwise
  258. * call the super class.
  259. * @param errorOutputToFlush The string to output.
  260. * @see Task#handleErrorFlush(String)
  261. * @since Ant 1.5.2
  262. */
  263. public void handleErrorFlush(String errorOutputToFlush) {
  264. if (newProject != null) {
  265. newProject.demuxFlush(errorOutputToFlush, true);
  266. } else {
  267. super.handleErrorFlush(errorOutputToFlush);
  268. }
  269. }
  270. /**
  271. * Do the execution.
  272. * @throws BuildException if a target tries to call itself;
  273. * probably also if a BuildException is thrown by the new project.
  274. */
  275. public void execute() throws BuildException {
  276. File savedDir = dir;
  277. String savedAntFile = antFile;
  278. Vector locals = new Vector(targets);
  279. try {
  280. getNewProject();
  281. if (dir == null && inheritAll) {
  282. dir = getProject().getBaseDir();
  283. }
  284. initializeProject();
  285. if (dir != null) {
  286. newProject.setBaseDir(dir);
  287. if (savedDir != null) {
  288. // has been set explicitly
  289. newProject.setInheritedProperty(MagicNames.PROJECT_BASEDIR,
  290. dir.getAbsolutePath());
  291. }
  292. } else {
  293. dir = getProject().getBaseDir();
  294. }
  295. overrideProperties();
  296. if (antFile == null) {
  297. antFile = Main.DEFAULT_BUILD_FILENAME;
  298. }
  299. File file = FILE_UTILS.resolveFile(dir, antFile);
  300. antFile = file.getAbsolutePath();
  301. log("calling target(s) "
  302. + ((locals.size() > 0) ? locals.toString() : "[default]")
  303. + " in build file " + antFile, Project.MSG_VERBOSE);
  304. newProject.setUserProperty(MagicNames.ANT_FILE , antFile);
  305. String thisAntFile = getProject().getProperty(MagicNames.ANT_FILE);
  306. // Are we trying to call the target in which we are defined (or
  307. // the build file if this is a top level task)?
  308. if (thisAntFile != null
  309. && file.equals(getProject().resolveFile(thisAntFile))
  310. && getOwningTarget() != null) {
  311. if (getOwningTarget().getName().equals("")) {
  312. if (getTaskName().equals("antcall")) {
  313. throw new BuildException("antcall must not be used at"
  314. + " the top level.");
  315. }
  316. throw new BuildException(getTaskName() + " task at the"
  317. + " top level must not invoke"
  318. + " its own build file.");
  319. }
  320. }
  321. try {
  322. ProjectHelper.configureProject(newProject, file);
  323. } catch (BuildException ex) {
  324. throw ProjectHelper.addLocationToBuildException(
  325. ex, getLocation());
  326. }
  327. if (locals.size() == 0) {
  328. String defaultTarget = newProject.getDefaultTarget();
  329. if (defaultTarget != null) {
  330. locals.add(defaultTarget);
  331. }
  332. }
  333. if (newProject.getProperty(MagicNames.ANT_FILE)
  334. .equals(getProject().getProperty(MagicNames.ANT_FILE))
  335. && getOwningTarget() != null) {
  336. String owningTargetName = getOwningTarget().getName();
  337. if (locals.contains(owningTargetName)) {
  338. throw new BuildException(getTaskName() + " task calling "
  339. + "its own parent target.");
  340. }
  341. boolean circular = false;
  342. for (Iterator it = locals.iterator();
  343. !circular && it.hasNext();) {
  344. Target other =
  345. (Target) (getProject().getTargets().get(it.next()));
  346. circular |= (other != null
  347. && other.dependsOn(owningTargetName));
  348. }
  349. if (circular) {
  350. throw new BuildException(getTaskName()
  351. + " task calling a target"
  352. + " that depends on"
  353. + " its parent target \'"
  354. + owningTargetName
  355. + "\'.");
  356. }
  357. }
  358. addReferences();
  359. if (locals.size() > 0 && !(locals.size() == 1
  360. && "".equals(locals.get(0)))) {
  361. BuildException be = null;
  362. try {
  363. log("Entering " + antFile + "...", Project.MSG_VERBOSE);
  364. newProject.fireSubBuildStarted();
  365. newProject.executeTargets(locals);
  366. } catch (BuildException ex) {
  367. be = ProjectHelper
  368. .addLocationToBuildException(ex, getLocation());
  369. throw be;
  370. } finally {
  371. log("Exiting " + antFile + ".", Project.MSG_VERBOSE);
  372. newProject.fireSubBuildFinished(be);
  373. }
  374. }
  375. } finally {
  376. // help the gc
  377. newProject = null;
  378. Enumeration e = properties.elements();
  379. while (e.hasMoreElements()) {
  380. Property p = (Property) e.nextElement();
  381. p.setProject(null);
  382. }
  383. if (output != null && out != null) {
  384. try {
  385. out.close();
  386. } catch (final Exception ex) {
  387. //ignore
  388. }
  389. }
  390. dir = savedDir;
  391. antFile = savedAntFile;
  392. }
  393. }
  394. /**
  395. * Override the properties in the new project with the one
  396. * explicitly defined as nested elements here.
  397. * @throws BuildException under unknown circumstances.
  398. */
  399. private void overrideProperties() throws BuildException {
  400. // remove duplicate properties - last property wins
  401. // Needed for backward compatibility
  402. Set set = new HashSet();
  403. for (int i = properties.size() - 1; i >= 0; --i) {
  404. Property p = (Property) properties.get(i);
  405. if (p.getName() != null && !p.getName().equals("")) {
  406. if (set.contains(p.getName())) {
  407. properties.remove(i);
  408. } else {
  409. set.add(p.getName());
  410. }
  411. }
  412. }
  413. Enumeration e = properties.elements();
  414. while (e.hasMoreElements()) {
  415. Property p = (Property) e.nextElement();
  416. p.setProject(newProject);
  417. p.execute();
  418. }
  419. getProject().copyInheritedProperties(newProject);
  420. }
  421. /**
  422. * Add the references explicitly defined as nested elements to the
  423. * new project. Also copy over all references that don't override
  424. * existing references in the new project if inheritrefs has been
  425. * requested.
  426. * @throws BuildException if a reference does not have a refid.
  427. */
  428. private void addReferences() throws BuildException {
  429. Hashtable thisReferences
  430. = (Hashtable) getProject().getReferences().clone();
  431. Hashtable newReferences = newProject.getReferences();
  432. Enumeration e;
  433. if (references.size() > 0) {
  434. for (e = references.elements(); e.hasMoreElements();) {
  435. Reference ref = (Reference) e.nextElement();
  436. String refid = ref.getRefId();
  437. if (refid == null) {
  438. throw new BuildException("the refid attribute is required"
  439. + " for reference elements");
  440. }
  441. if (!thisReferences.containsKey(refid)) {
  442. log("Parent project doesn't contain any reference '"
  443. + refid + "'",
  444. Project.MSG_WARN);
  445. continue;
  446. }
  447. thisReferences.remove(refid);
  448. String toRefid = ref.getToRefid();
  449. if (toRefid == null) {
  450. toRefid = refid;
  451. }
  452. copyReference(refid, toRefid);
  453. }
  454. }
  455. // Now add all references that are not defined in the
  456. // subproject, if inheritRefs is true
  457. if (inheritRefs) {
  458. for (e = thisReferences.keys(); e.hasMoreElements();) {
  459. String key = (String) e.nextElement();
  460. if (newReferences.containsKey(key)) {
  461. continue;
  462. }
  463. copyReference(key, key);
  464. newProject.inheritIDReferences(getProject());
  465. }
  466. }
  467. }
  468. /**
  469. * Try to clone and reconfigure the object referenced by oldkey in
  470. * the parent project and add it to the new project with the key newkey.
  471. *
  472. * <p>If we cannot clone it, copy the referenced object itself and
  473. * keep our fingers crossed.</p>
  474. * @param oldKey the reference id in the current project.
  475. * @param newKey the reference id in the new project.
  476. */
  477. private void copyReference(String oldKey, String newKey) {
  478. Object orig = getProject().getReference(oldKey);
  479. if (orig == null) {
  480. log("No object referenced by " + oldKey + ". Can't copy to "
  481. + newKey,
  482. Project.MSG_WARN);
  483. return;
  484. }
  485. Class c = orig.getClass();
  486. Object copy = orig;
  487. try {
  488. Method cloneM = c.getMethod("clone", new Class[0]);
  489. if (cloneM != null) {
  490. copy = cloneM.invoke(orig, new Object[0]);
  491. log("Adding clone of reference " + oldKey, Project.MSG_DEBUG);
  492. }
  493. } catch (Exception e) {
  494. // not Clonable
  495. }
  496. if (copy instanceof ProjectComponent) {
  497. ((ProjectComponent) copy).setProject(newProject);
  498. } else {
  499. try {
  500. Method setProjectM =
  501. c.getMethod("setProject", new Class[] {Project.class});
  502. if (setProjectM != null) {
  503. setProjectM.invoke(copy, new Object[] {newProject});
  504. }
  505. } catch (NoSuchMethodException e) {
  506. // ignore this if the class being referenced does not have
  507. // a set project method.
  508. } catch (Exception e2) {
  509. String msg = "Error setting new project instance for "
  510. + "reference with id " + oldKey;
  511. throw new BuildException(msg, e2, getLocation());
  512. }
  513. }
  514. newProject.addReference(newKey, copy);
  515. }
  516. /**
  517. * Copies all properties from the given table to the new project -
  518. * omitting those that have already been set in the new project as
  519. * well as properties named basedir or ant.file.
  520. * @param props properties <code>Hashtable</code> to copy to the
  521. * new project.
  522. * @since Ant 1.6
  523. */
  524. private void addAlmostAll(Hashtable props) {
  525. Enumeration e = props.keys();
  526. while (e.hasMoreElements()) {
  527. String key = e.nextElement().toString();
  528. if (MagicNames.PROJECT_BASEDIR.equals(key) || MagicNames.ANT_FILE.equals(key)) {
  529. // basedir and ant.file get special treatment in execute()
  530. continue;
  531. }
  532. String value = props.get(key).toString();
  533. // don't re-set user properties, avoid the warning message
  534. if (newProject.getProperty(key) == null) {
  535. // no user property
  536. newProject.setNewProperty(key, value);
  537. }
  538. }
  539. }
  540. /**
  541. * The directory to use as a base directory for the new Ant project.
  542. * Defaults to the current project's basedir, unless inheritall
  543. * has been set to false, in which case it doesn't have a default
  544. * value. This will override the basedir setting of the called project.
  545. * @param dir new directory as <code>File</code>.
  546. */
  547. public void setDir(File dir) {
  548. this.dir = dir;
  549. }
  550. /**
  551. * The build file to use. Defaults to "build.xml". This file is expected
  552. * to be a filename relative to the dir attribute given.
  553. * @param antFile the <code>String</code> build file name.
  554. */
  555. public void setAntfile(String antFile) {
  556. // @note: it is a string and not a file to handle relative/absolute
  557. // otherwise a relative file will be resolved based on the current
  558. // basedir.
  559. this.antFile = antFile;
  560. }
  561. /**
  562. * The target of the new Ant project to execute.
  563. * Defaults to the new project's default target.
  564. * @param targetToAdd the name of the target to invoke.
  565. */
  566. public void setTarget(String targetToAdd) {
  567. if (targetToAdd.equals("")) {
  568. throw new BuildException("target attribute must not be empty");
  569. }
  570. targets.add(targetToAdd);
  571. targetAttributeSet = true;
  572. }
  573. /**
  574. * Set the filename to write the output to. This is relative to the value
  575. * of the dir attribute if it has been set or to the base directory of the
  576. * current project otherwise.
  577. * @param outputFile the name of the file to which the output should go.
  578. */
  579. public void setOutput(String outputFile) {
  580. this.output = outputFile;
  581. }
  582. /**
  583. * Property to pass to the new project.
  584. * The property is passed as a 'user property'.
  585. * @return the created <code>Property</code> object.
  586. */
  587. public Property createProperty() {
  588. Property p = new Property(true, getProject());
  589. p.setProject(getNewProject());
  590. p.setTaskName("property");
  591. properties.addElement(p);
  592. return p;
  593. }
  594. /**
  595. * Add a Reference element identifying a data type to carry
  596. * over to the new project.
  597. * @param ref <code>Reference</code> to add.
  598. */
  599. public void addReference(Reference ref) {
  600. references.addElement(ref);
  601. }
  602. /**
  603. * Add a target to this Ant invocation.
  604. * @param t the <code>TargetElement</code> to add.
  605. * @since Ant 1.6.3
  606. */
  607. public void addConfiguredTarget(TargetElement t) {
  608. if (targetAttributeSet) {
  609. throw new BuildException(
  610. "nested target is incompatible with the target attribute");
  611. }
  612. String name = t.getName();
  613. if (name.equals("")) {
  614. throw new BuildException("target name must not be empty");
  615. }
  616. targets.add(name);
  617. }
  618. /**
  619. * Add a set of properties to pass to the new project.
  620. *
  621. * @param ps <code>PropertySet</code> to add.
  622. * @since Ant 1.6
  623. */
  624. public void addPropertyset(PropertySet ps) {
  625. propertySets.addElement(ps);
  626. }
  627. /**
  628. * Get the (sub)-Project instance currently in use.
  629. * @return Project
  630. * @since Ant 1.7
  631. */
  632. protected Project getNewProject() {
  633. if (newProject == null) {
  634. reinit();
  635. }
  636. return newProject;
  637. }
  638. /**
  639. * @since Ant 1.6.2
  640. */
  641. private Iterator getBuildListeners() {
  642. return getProject().getBuildListeners().iterator();
  643. }
  644. /**
  645. * Helper class that implements the nested &lt;reference&gt;
  646. * element of &lt;ant&gt; and &lt;antcall&gt;.
  647. */
  648. public static class Reference
  649. extends org.apache.tools.ant.types.Reference {
  650. /** Creates a reference to be configured by Ant. */
  651. public Reference() {
  652. super();
  653. }
  654. private String targetid = null;
  655. /**
  656. * Set the id that this reference to be stored under in the
  657. * new project.
  658. *
  659. * @param targetid the id under which this reference will be passed to
  660. * the new project. */
  661. public void setToRefid(String targetid) {
  662. this.targetid = targetid;
  663. }
  664. /**
  665. * Get the id under which this reference will be stored in the new
  666. * project.
  667. *
  668. * @return the id of the reference in the new project.
  669. */
  670. public String getToRefid() {
  671. return targetid;
  672. }
  673. }
  674. /**
  675. * Helper class that implements the nested &lt;target&gt;
  676. * element of &lt;ant&gt; and &lt;antcall&gt;.
  677. * @since Ant 1.6.3
  678. */
  679. public static class TargetElement {
  680. private String name;
  681. /**
  682. * Default constructor.
  683. */
  684. public TargetElement() {
  685. //default
  686. }
  687. /**
  688. * Set the name of this TargetElement.
  689. * @param name the <code>String</code> target name.
  690. */
  691. public void setName(String name) {
  692. this.name = name;
  693. }
  694. /**
  695. * Get the name of this TargetElement.
  696. * @return <code>String</code>.
  697. */
  698. public String getName() {
  699. return name;
  700. }
  701. }
  702. }