1. /*
  2. * Copyright 2000-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.types;
  18. import org.apache.tools.ant.BuildException;
  19. import org.apache.tools.ant.Project;
  20. import java.util.ArrayList;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.ListIterator;
  24. /**
  25. * The assertion datatype. This type describes
  26. * assertion settings for the <java> task and others.
  27. * One can set the system assertions, and enable/disable those in
  28. * packages and classes.
  29. * Assertions can only be enabled or disabled when forking Java.
  30. *
  31. * Example: set system assertions and all org.apache packages except
  32. * for ant, and the class org.apache.tools.ant.Main.
  33. * <pre>
  34. * <assertions enableSystemAssertions="true" >
  35. * <enable package="org.apache" />
  36. * <disable package="org.apache.ant" />
  37. * <enable class="org.apache.tools.ant.Main"/>
  38. * </assertions>
  39. *</pre>
  40. * Disable system assertions; enable those in the anonymous package
  41. * <pre>
  42. * <assertions enableSystemAssertions="false" >
  43. * <enable package="..." />
  44. * </assertions>
  45. * </pre>
  46. * enable assertions in a class called Test
  47. * <pre>
  48. * <assertions >
  49. * <enable class="Test" />
  50. * </assertions>
  51. * </pre>
  52. * This type is a datatype, so you can declare assertions and use them later
  53. *
  54. * <pre>
  55. * <assertions id="project.assertions" >
  56. * <enable project="org.apache.test" />
  57. * </assertions>
  58. *
  59. * <assertions refid="project.assertions" />
  60. *
  61. * </pre>
  62. * @since Ant 1.6
  63. */
  64. public class Assertions extends DataType implements Cloneable {
  65. /**
  66. * enable/disable sys assertions; null means undefined
  67. */
  68. private Boolean enableSystemAssertions;
  69. /**
  70. * list of type BaseAssertion
  71. */
  72. private ArrayList assertionList = new ArrayList();
  73. /**
  74. * enable assertions
  75. * @param assertion
  76. */
  77. public void addEnable(EnabledAssertion assertion) {
  78. checkChildrenAllowed();
  79. assertionList.add(assertion);
  80. }
  81. /**
  82. * disable assertions
  83. * @param assertion
  84. */
  85. public void addDisable(DisabledAssertion assertion) {
  86. checkChildrenAllowed();
  87. assertionList.add(assertion);
  88. }
  89. /**
  90. * enable or disable system assertions
  91. * @param enableSystemAssertions
  92. */
  93. public void setEnableSystemAssertions(Boolean enableSystemAssertions) {
  94. checkAttributesAllowed();
  95. this.enableSystemAssertions = enableSystemAssertions;
  96. }
  97. /**
  98. * Set the value of the refid attribute.
  99. *
  100. * <p>Subclasses may need to check whether any other attributes
  101. * have been set as well or child elements have been created and
  102. * thus override this method. if they do the must call
  103. * <code>super.setRefid</code>.</p>
  104. */
  105. public void setRefid(Reference ref) {
  106. if (assertionList.size() > 0 || enableSystemAssertions != null) {
  107. throw tooManyAttributes();
  108. }
  109. super.setRefid(ref);
  110. }
  111. /**
  112. * get whatever we are referencing to. This could be ourself.
  113. * @return the object that contains the assertion info
  114. */
  115. private Assertions getFinalReference() {
  116. if (getRefid() == null) {
  117. return this;
  118. } else {
  119. Object o = getRefid().getReferencedObject(getProject());
  120. if (!(o instanceof Assertions)) {
  121. throw new BuildException("reference is of wrong type");
  122. }
  123. return (Assertions) o;
  124. }
  125. }
  126. /**
  127. * how many assertions are made...will resolve references before returning
  128. * @return total # of commands to make
  129. */
  130. public int size() {
  131. Assertions clause = getFinalReference();
  132. return clause.getFinalSize();
  133. }
  134. /**
  135. * what is the final size of this object
  136. * @return
  137. */
  138. private int getFinalSize() {
  139. return assertionList.size() + (enableSystemAssertions != null ? 1 : 0);
  140. }
  141. /**
  142. * add the assertions to a list in a format suitable
  143. * for adding to a command line
  144. * @param commandList
  145. */
  146. public void applyAssertions(List commandList) {
  147. getProject().log("Applying assertions",Project.MSG_DEBUG);
  148. Assertions clause = getFinalReference();
  149. //do the system assertions
  150. if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
  151. getProject().log("Enabling system assertions", Project.MSG_DEBUG);
  152. commandList.add("-enablesystemassertions");
  153. } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
  154. getProject().log("disabling system assertions", Project.MSG_DEBUG);
  155. commandList.add("-disablesystemassertions");
  156. }
  157. //now any inner assertions
  158. Iterator it = clause.assertionList.iterator();
  159. while (it.hasNext()) {
  160. BaseAssertion assertion = (BaseAssertion) it.next();
  161. String arg = assertion.toCommand();
  162. getProject().log("adding assertion "+arg, Project.MSG_DEBUG);
  163. commandList.add(arg);
  164. }
  165. }
  166. /**
  167. * apply all the assertions to the command.
  168. * @param command
  169. */
  170. public void applyAssertions(CommandlineJava command) {
  171. Assertions clause = getFinalReference();
  172. //do the system assertions
  173. if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
  174. addVmArgument(command, "-enablesystemassertions");
  175. } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
  176. addVmArgument(command, "-disablesystemassertions");
  177. }
  178. //now any inner assertions
  179. Iterator it = clause.assertionList.iterator();
  180. while (it.hasNext()) {
  181. BaseAssertion assertion = (BaseAssertion) it.next();
  182. String arg = assertion.toCommand();
  183. addVmArgument(command, arg);
  184. }
  185. }
  186. /**
  187. * add the assertions to a list in a format suitable
  188. * for adding to a command line
  189. * @param commandList
  190. */
  191. public void applyAssertions(final ListIterator commandIterator) {
  192. getProject().log("Applying assertions", Project.MSG_DEBUG);
  193. Assertions clause = getFinalReference();
  194. //do the system assertions
  195. if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
  196. getProject().log("Enabling system assertions", Project.MSG_DEBUG);
  197. commandIterator.add("-enablesystemassertions");
  198. } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
  199. getProject().log("disabling system assertions", Project.MSG_DEBUG);
  200. commandIterator.add("-disablesystemassertions");
  201. }
  202. //now any inner assertions
  203. Iterator it = clause.assertionList.iterator();
  204. while (it.hasNext()) {
  205. BaseAssertion assertion = (BaseAssertion) it.next();
  206. String arg = assertion.toCommand();
  207. getProject().log("adding assertion "+arg, Project.MSG_DEBUG);
  208. commandIterator.add(arg);
  209. }
  210. }
  211. /**
  212. * helper method to add a string JVM argument to a command
  213. * @param command
  214. * @param arg
  215. */
  216. private static void addVmArgument(CommandlineJava command, String arg) {
  217. Commandline.Argument argument;
  218. argument = command.createVmArgument();
  219. argument.setValue(arg);
  220. }
  221. /**
  222. * clone the objects.
  223. * This is not a full depth clone; the list of assertions is cloned,
  224. * but it does not clone the underlying assertions.
  225. * @return a cli
  226. * @throws CloneNotSupportedException
  227. */
  228. public Object clone() throws CloneNotSupportedException {
  229. Assertions that = (Assertions) super.clone();
  230. that.assertionList = (ArrayList) assertionList.clone();
  231. return that;
  232. }
  233. /**
  234. * base class for our assertion elements.
  235. */
  236. public abstract static class BaseAssertion {
  237. private String packageName;
  238. private String className;
  239. /**
  240. * name a class
  241. * @param className
  242. */
  243. public void setClass(String className) {
  244. this.className = className;
  245. }
  246. /**
  247. * name a package
  248. * @param packageName
  249. */
  250. public void setPackage(String packageName) {
  251. this.packageName = packageName;
  252. }
  253. /**
  254. * what is the class name?
  255. * @return classname or null
  256. * @see #setClass
  257. */
  258. protected String getClassName() {
  259. return className;
  260. }
  261. /**
  262. * what is the package name?
  263. * @return package name or null
  264. * @see #setPackage
  265. */
  266. protected String getPackageName() {
  267. return packageName;
  268. }
  269. /**
  270. * get the prefix used to begin the command; -ea or -da.
  271. * @return prefix
  272. */
  273. public abstract String getCommandPrefix();
  274. /**
  275. * create a full command string from this class
  276. * @throws BuildException in case of trouble
  277. * @return The command string
  278. */
  279. public String toCommand() {
  280. //catch invalidness
  281. if (getPackageName() != null && getClassName() != null) {
  282. throw new BuildException("Both package and class have been set");
  283. }
  284. StringBuffer command = new StringBuffer(getCommandPrefix());
  285. //see if it is a package or a class
  286. if (getPackageName() != null) {
  287. //packages get a ... prefix
  288. command.append(':');
  289. command.append(getPackageName());
  290. if (!command.toString().endsWith("...")) {
  291. //append the ... suffix if not there already
  292. command.append("...");
  293. }
  294. } else if (getClassName() != null) {
  295. //classes just get the classname
  296. command.append(':');
  297. command.append(getClassName());
  298. }
  299. return command.toString();
  300. }
  301. }
  302. /**
  303. * an enabled assertion enables things
  304. */
  305. public static class EnabledAssertion extends BaseAssertion {
  306. /**
  307. * get the prefix used to begin the command; -ea or -da.
  308. * @return prefix
  309. */
  310. public String getCommandPrefix() {
  311. return "-ea";
  312. }
  313. }
  314. /**
  315. * A disabled assertion disables things
  316. */
  317. public static class DisabledAssertion extends BaseAssertion {
  318. /**
  319. * get the prefix used to begin the command; -ea or -da.
  320. * @return prefix
  321. */
  322. public String getCommandPrefix() {
  323. return "-da";
  324. }
  325. }
  326. }