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. /*
  18. * Portions of this software are based upon public domain software
  19. * originally written at the National Center for Supercomputing Applications,
  20. * University of Illinois, Urbana-Champaign.
  21. */
  22. package org.apache.tools.ant.taskdefs.optional.perforce;
  23. import org.apache.tools.ant.BuildException;
  24. import org.apache.tools.ant.Project;
  25. /**
  26. * Requests a new changelist from the Perforce server.
  27. * P4Change creates a new changelist in perforce. P4Change sets the property
  28. * ${p4.change} with the new changelist number. This should then be passed into
  29. * p4edit and p4submit.
  30. *
  31. *
  32. * @see P4Edit
  33. * @see P4Submit
  34. *
  35. * @ant.task category="scm"
  36. */
  37. public class P4Change extends P4Base {
  38. protected String emptyChangeList = null;
  39. protected String description = "AutoSubmit By Ant";
  40. /**
  41. * creates a new Perforce change list
  42. * sets the p4.change property to the number of the new change list
  43. * @throws BuildException if the word error appears in the output coming from Perforce
  44. */
  45. public void execute() throws BuildException {
  46. if (emptyChangeList == null) {
  47. emptyChangeList = getEmptyChangeList();
  48. }
  49. final Project myProj = getProject();
  50. P4Handler handler = new P4HandlerAdapter() {
  51. public void process(String line) {
  52. if (util.match("/Change/", line)) {
  53. //Remove any non-numerical chars - should leave the change number
  54. line = util.substitute("s/[^0-9]//g", line);
  55. int changenumber = Integer.parseInt(line);
  56. log("Change Number is " + changenumber, Project.MSG_INFO);
  57. myProj.setProperty("p4.change", "" + changenumber);
  58. } else if (util.match("/error/", line)) {
  59. throw new BuildException("Perforce Error, check client settings and/or server");
  60. }
  61. }
  62. };
  63. handler.setOutput(emptyChangeList);
  64. execP4Command("change -i", handler);
  65. }
  66. /**
  67. * returns the text of an empty change list
  68. * @return the text of an empty change list
  69. * @throws BuildException if the text error is displayed
  70. * in the Perforce output outside of a comment line
  71. */
  72. public String getEmptyChangeList() throws BuildException {
  73. final StringBuffer stringbuf = new StringBuffer();
  74. execP4Command("change -o", new P4HandlerAdapter() {
  75. public void process(String line) {
  76. if (!util.match("/^#/", line)) {
  77. if (util.match("/error/", line)) {
  78. log("Client Error", Project.MSG_VERBOSE);
  79. throw new BuildException("Perforce Error, "
  80. + "check client settings and/or server");
  81. } else if (util.match("/<enter description here>/", line)) {
  82. // we need to escape the description in case there are /
  83. description = backslash(description);
  84. line = util.substitute("s/<enter description here>/"
  85. + description + "/", line);
  86. } else if (util.match("/\\/\\//", line)) {
  87. //Match "//" for begining of depot filespec
  88. return;
  89. }
  90. stringbuf.append(line);
  91. stringbuf.append("\n");
  92. }
  93. }
  94. });
  95. return stringbuf.toString();
  96. }
  97. /**
  98. * Ensure that a string is backslashing slashes so that it does not
  99. * confuse them with Perl substitution delimiter in Oro. Backslashes are
  100. * always backslashes in a string unless they escape the delimiter.
  101. * @param value the string to backslash for slashes
  102. * @return the backslashed string
  103. * @see <a href="http://jakarta.apache.org/oro/api/org/apache/oro/text/perl/Perl5Util.html
  104. * #substitute(java.lang.String,%20java.lang.String)">Oro</a>
  105. */
  106. public static final String backslash(String value) {
  107. final StringBuffer buf = new StringBuffer(value.length());
  108. final int len = value.length();
  109. for (int i = 0; i < len; i++) {
  110. char c = value.charAt(i);
  111. if (c == '/') {
  112. buf.append('\\');
  113. }
  114. buf.append(c);
  115. }
  116. return buf.toString();
  117. }
  118. /**
  119. * Description for ChangeList;optional.
  120. * If none is specified, it will default to "AutoSubmit By Ant"
  121. * @param desc description for the change list
  122. */
  123. public void setDescription(String desc) {
  124. this.description = desc;
  125. }
  126. } //EoF