1. /*
  2. * Copyright 2001-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.taskdefs;
  18. import java.util.Hashtable;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.taskdefs.condition.Condition;
  21. import org.apache.tools.ant.taskdefs.condition.ConditionBase;
  22. import org.apache.tools.ant.types.EnumeratedAttribute;
  23. /**
  24. * Wait for an external event to occur.
  25. *
  26. * Wait for an external process to start or to complete some
  27. * task. This is useful with the <code>parallel</code> task to
  28. * synchronize the execution of tests with server startup.
  29. *
  30. * The following attributes can be specified on a waitfor task:
  31. * <ul>
  32. * <li>maxwait - maximum length of time to wait before giving up</li>
  33. * <li>maxwaitunit - The unit to be used to interpret maxwait attribute</li>
  34. * <li>checkevery - amount of time to sleep between each check</li>
  35. * <li>checkeveryunit - The unit to be used to interpret checkevery attribute</li>
  36. * <li>timeoutproperty - name of a property to set if maxwait has been exceeded.</li>
  37. * </ul>
  38. *
  39. * The maxwaitunit and checkeveryunit are allowed to have the following values:
  40. * millisecond, second, minute, hour, day and week. The default is millisecond.
  41. *
  42. * @since Ant 1.5
  43. *
  44. * @ant.task category="control"
  45. */
  46. public class WaitFor extends ConditionBase {
  47. /** default max wait time */
  48. private long maxWaitMillis = 1000L * 60L * 3L;
  49. private long maxWaitMultiplier = 1L;
  50. private long checkEveryMillis = 500L;
  51. private long checkEveryMultiplier = 1L;
  52. private String timeoutProperty;
  53. /**
  54. * Set the maximum length of time to wait
  55. */
  56. public void setMaxWait(long time) {
  57. maxWaitMillis = time;
  58. }
  59. /**
  60. * Set the max wait time unit
  61. */
  62. public void setMaxWaitUnit(Unit unit) {
  63. maxWaitMultiplier = unit.getMultiplier();
  64. }
  65. /**
  66. * Set the time between each check
  67. */
  68. public void setCheckEvery(long time) {
  69. checkEveryMillis = time;
  70. }
  71. /**
  72. * Set the check every time unit
  73. */
  74. public void setCheckEveryUnit(Unit unit) {
  75. checkEveryMultiplier = unit.getMultiplier();
  76. }
  77. /**
  78. * Name the property to set after a timeout.
  79. */
  80. public void setTimeoutProperty(String p) {
  81. timeoutProperty = p;
  82. }
  83. /**
  84. * Check repeatedly for the specified conditions until they become
  85. * true or the timeout expires.
  86. */
  87. public void execute() throws BuildException {
  88. if (countConditions() > 1) {
  89. throw new BuildException("You must not nest more than one "
  90. + "condition into <waitfor>");
  91. }
  92. if (countConditions() < 1) {
  93. throw new BuildException("You must nest a condition into "
  94. + "<waitfor>");
  95. }
  96. Condition c = (Condition) getConditions().nextElement();
  97. long savedMaxWaitMillis = maxWaitMillis;
  98. long savedCheckEveryMillis = checkEveryMillis;
  99. try {
  100. maxWaitMillis *= maxWaitMultiplier;
  101. checkEveryMillis *= checkEveryMultiplier;
  102. long start = System.currentTimeMillis();
  103. long end = start + maxWaitMillis;
  104. while (System.currentTimeMillis() < end) {
  105. if (c.eval()) {
  106. return;
  107. }
  108. try {
  109. Thread.sleep(checkEveryMillis);
  110. } catch (InterruptedException e) {
  111. // ignore
  112. }
  113. }
  114. if (timeoutProperty != null) {
  115. getProject().setNewProperty(timeoutProperty, "true");
  116. }
  117. } finally {
  118. maxWaitMillis = savedMaxWaitMillis;
  119. checkEveryMillis = savedCheckEveryMillis;
  120. }
  121. }
  122. /**
  123. * The enumeration of units:
  124. * millisecond, second, minute, hour, day, week
  125. * @todo we use timestamps in many places, why not factor this out
  126. */
  127. public static class Unit extends EnumeratedAttribute {
  128. private static final String MILLISECOND = "millisecond";
  129. private static final String SECOND = "second";
  130. private static final String MINUTE = "minute";
  131. private static final String HOUR = "hour";
  132. private static final String DAY = "day";
  133. private static final String WEEK = "week";
  134. private static final String[] units = {
  135. MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK
  136. };
  137. private Hashtable timeTable = new Hashtable();
  138. public Unit() {
  139. timeTable.put(MILLISECOND, new Long(1L));
  140. timeTable.put(SECOND, new Long(1000L));
  141. timeTable.put(MINUTE, new Long(1000L * 60L));
  142. timeTable.put(HOUR, new Long(1000L * 60L * 60L));
  143. timeTable.put(DAY, new Long(1000L * 60L * 60L * 24L));
  144. timeTable.put(WEEK, new Long(1000L * 60L * 60L * 24L * 7L));
  145. }
  146. public long getMultiplier() {
  147. String key = getValue().toLowerCase();
  148. Long l = (Long) timeTable.get(key);
  149. return l.longValue();
  150. }
  151. public String[] getValues() {
  152. return units;
  153. }
  154. }
  155. }