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.

Exit.java 7.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 org.apache.tools.ant.Project;
  20. import org.apache.tools.ant.Task;
  21. import org.apache.tools.ant.BuildException;
  22. import org.apache.tools.ant.ExitStatusException;
  23. import org.apache.tools.ant.taskdefs.condition.Condition;
  24. import org.apache.tools.ant.taskdefs.condition.ConditionBase;
  25. /**
  26. * Exits the active build, giving an additional message
  27. * if available.
  28. *
  29. * The <code>if</code> and <code>unless</code> attributes make the
  30. * failure conditional -both probe for the named property being defined.
  31. * The <code>if</code> tests for the property being defined, the
  32. * <code>unless</code> for a property being undefined.
  33. *
  34. * If both attributes are set, then the test fails only if both tests
  35. * are true. i.e.
  36. * <pre>fail := defined(ifProperty) && !defined(unlessProperty)</pre>
  37. *
  38. * A single nested<code>&lt;condition&gt;</code> element can be specified
  39. * instead of using <code>if</code>/<code>unless</code> (a combined
  40. * effect can be achieved using <code>isset</code> conditions).
  41. *
  42. * @since Ant 1.2
  43. *
  44. * @ant.task name="fail" category="control"
  45. */
  46. public class Exit extends Task {
  47. private static class NestedCondition extends ConditionBase implements Condition {
  48. public boolean eval() {
  49. if (countConditions() != 1) {
  50. throw new BuildException(
  51. "A single nested condition is required.");
  52. }
  53. return ((Condition) (getConditions().nextElement())).eval();
  54. }
  55. }
  56. private String message;
  57. private String ifCondition, unlessCondition;
  58. private NestedCondition nestedCondition;
  59. private Integer status;
  60. /**
  61. * A message giving further information on why the build exited.
  62. *
  63. * @param value message to output
  64. */
  65. public void setMessage(String value) {
  66. this.message = value;
  67. }
  68. /**
  69. * Only fail if a property of the given name exists in the current project.
  70. * @param c property name
  71. */
  72. public void setIf(String c) {
  73. ifCondition = c;
  74. }
  75. /**
  76. * Only fail if a property of the given name does not
  77. * exist in the current project.
  78. * @param c property name
  79. */
  80. public void setUnless(String c) {
  81. unlessCondition = c;
  82. }
  83. /**
  84. * Set the status code to associate with the thrown Exception.
  85. * @param i the <code>int</code> status
  86. */
  87. public void setStatus(int i) {
  88. status = new Integer(i);
  89. }
  90. /**
  91. * Throw a <code>BuildException</code> to exit (fail) the build.
  92. * If specified, evaluate conditions:
  93. * A single nested condition is accepted, but requires that the
  94. * <code>if</code>/<code>unless</code> attributes be omitted.
  95. * If the nested condition evaluates to true, or the
  96. * ifCondition is true or unlessCondition is false, the build will exit.
  97. * The error message is constructed from the text fields, from
  98. * the nested condition (if specified), or finally from
  99. * the if and unless parameters (if present).
  100. * @throws BuildException on error
  101. */
  102. public void execute() throws BuildException {
  103. boolean fail = (nestedConditionPresent()) ? testNestedCondition()
  104. : (testIfCondition() && testUnlessCondition());
  105. if (fail) {
  106. String text = null;
  107. if (message != null && message.trim().length() > 0) {
  108. text = message.trim();
  109. } else {
  110. if (ifCondition != null && ifCondition.length() > 0
  111. && getProject().getProperty(ifCondition) != null) {
  112. text = "if=" + ifCondition;
  113. }
  114. if (unlessCondition != null && unlessCondition.length() > 0
  115. && getProject().getProperty(unlessCondition) == null) {
  116. if (text == null) {
  117. text = "";
  118. } else {
  119. text += " and ";
  120. }
  121. text += "unless=" + unlessCondition;
  122. }
  123. if (nestedConditionPresent()) {
  124. text = "condition satisfied";
  125. } else {
  126. if (text == null) {
  127. text = "No message";
  128. }
  129. }
  130. }
  131. log("failing due to " + text, Project.MSG_DEBUG);
  132. throw ((status == null) ? new BuildException(text)
  133. : new ExitStatusException(text, status.intValue()));
  134. }
  135. }
  136. /**
  137. * Set a multiline message.
  138. * @param msg the message to display
  139. */
  140. public void addText(String msg) {
  141. if (message == null) {
  142. message = "";
  143. }
  144. message += getProject().replaceProperties(msg);
  145. }
  146. /**
  147. * Add a condition element.
  148. * @return <code>ConditionBase</code>.
  149. * @since Ant 1.6.2
  150. */
  151. public ConditionBase createCondition() {
  152. if (nestedCondition != null) {
  153. throw new BuildException("Only one nested condition is allowed.");
  154. }
  155. nestedCondition = new NestedCondition();
  156. return nestedCondition;
  157. }
  158. /**
  159. * test the if condition
  160. * @return true if there is no if condition, or the named property exists
  161. */
  162. private boolean testIfCondition() {
  163. if (ifCondition == null || "".equals(ifCondition)) {
  164. return true;
  165. }
  166. return getProject().getProperty(ifCondition) != null;
  167. }
  168. /**
  169. * test the unless condition
  170. * @return true if there is no unless condition,
  171. * or there is a named property but it doesn't exist
  172. */
  173. private boolean testUnlessCondition() {
  174. if (unlessCondition == null || "".equals(unlessCondition)) {
  175. return true;
  176. }
  177. return getProject().getProperty(unlessCondition) == null;
  178. }
  179. /**
  180. * test the nested condition
  181. * @return true if there is none, or it evaluates to true
  182. */
  183. private boolean testNestedCondition() {
  184. boolean result = nestedConditionPresent();
  185. if (result && ifCondition != null || unlessCondition != null) {
  186. throw new BuildException("Nested conditions "
  187. + "not permitted in conjunction with if/unless attributes");
  188. }
  189. return result && nestedCondition.eval();
  190. }
  191. /**
  192. * test whether there is a nested condition.
  193. * @return <code>boolean</code>.
  194. */
  195. private boolean nestedConditionPresent() {
  196. return (nestedCondition != null);
  197. }
  198. }