001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: /*
019: * Portions of this software are based upon public domain software
020: * originally written at the National Center for Supercomputing Applications,
021: * University of Illinois, Urbana-Champaign.
022: */
023:
024: package org.apache.tools.ant.taskdefs.optional.perforce;
025:
026: import org.apache.tools.ant.BuildException;
027: import org.apache.tools.ant.Project;
028:
029: /**
030: * Requests a new changelist from the Perforce server.
031: * P4Change creates a new changelist in perforce. P4Change sets the property
032: * ${p4.change} with the new changelist number. This should then be passed into
033: * p4edit and p4submit.
034: *
035: *
036: * @see P4Edit
037: * @see P4Submit
038: *
039: * @ant.task category="scm"
040: */
041: public class P4Change extends P4Base {
042: // CheckStyle:VisibilityModifier OFF - bc
043:
044: protected String emptyChangeList = null;
045: protected String description = "AutoSubmit By Ant";
046:
047: // CheckStyle:VisibilityModifier ON
048:
049: /**
050: * creates a new Perforce change list
051: * sets the p4.change property to the number of the new change list
052: * @throws BuildException if the word error appears in the output coming from Perforce
053: */
054: public void execute() throws BuildException {
055:
056: if (emptyChangeList == null) {
057: emptyChangeList = getEmptyChangeList();
058: }
059: final Project myProj = getProject();
060:
061: P4Handler handler = new P4HandlerAdapter() {
062: public void process(String line) {
063: if (util.match("/Change/", line)) {
064:
065: //Remove any non-numerical chars - should leave the change number
066: line = util.substitute("s/[^0-9]//g", line);
067:
068: int changenumber = Integer.parseInt(line);
069: log("Change Number is " + changenumber,
070: Project.MSG_INFO);
071: myProj.setProperty("p4.change", "" + changenumber);
072:
073: } else if (util.match("/error/", line)) {
074: throw new BuildException(
075: "Perforce Error, check client settings and/or server");
076: }
077:
078: }
079: };
080:
081: handler.setOutput(emptyChangeList);
082:
083: execP4Command("change -i", handler);
084: }
085:
086: /**
087: * returns the text of an empty change list
088: * @return the text of an empty change list
089: * @throws BuildException if the text error is displayed
090: * in the Perforce output outside of a comment line
091: */
092: public String getEmptyChangeList() throws BuildException {
093: final StringBuffer stringbuf = new StringBuffer();
094:
095: execP4Command("change -o", new P4HandlerAdapter() {
096: public void process(String line) {
097: if (!util.match("/^#/", line)) {
098: if (util.match("/error/", line)) {
099: log("Client Error", Project.MSG_VERBOSE);
100: throw new BuildException("Perforce Error, "
101: + "check client settings and/or server");
102: } else if (util.match("/<enter description here>/",
103: line)) {
104: // we need to escape the description in case there are /
105: description = backslash(description);
106: line = util.substitute(
107: "s/<enter description here>/"
108: + description + "/", line);
109: } else if (util.match("/\\/\\//", line)) {
110: //Match "//" for begining of depot filespec
111: return;
112: }
113: stringbuf.append(line);
114: stringbuf.append("\n");
115: }
116: }
117: });
118: return stringbuf.toString();
119: }
120:
121: /**
122: * Ensure that a string is backslashing slashes so that it does not
123: * confuse them with Perl substitution delimiter in Oro. Backslashes are
124: * always backslashes in a string unless they escape the delimiter.
125: * @param value the string to backslash for slashes
126: * @return the backslashed string
127: * @see <a href="http://jakarta.apache.org/oro/api/org/apache/oro/text/perl/Perl5Util.html
128: * #substitute(java.lang.String,%20java.lang.String)">Oro</a>
129: */
130: public static final String backslash(String value) {
131: final StringBuffer buf = new StringBuffer(value.length());
132: final int len = value.length();
133: for (int i = 0; i < len; i++) {
134: char c = value.charAt(i);
135: if (c == '/') {
136: buf.append('\\');
137: }
138: buf.append(c);
139: }
140: return buf.toString();
141: }
142:
143: /**
144: * Description for ChangeList;optional.
145: * If none is specified, it will default to "AutoSubmit By Ant"
146: * @param desc description for the change list
147: */
148: public void setDescription(String desc) {
149: this .description = desc;
150: }
151:
152: } //EoF
|