1. /*
  2. * Copyright 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.optional.clearcase;
  18. import org.apache.tools.ant.BuildException;
  19. import org.apache.tools.ant.Project;
  20. import org.apache.tools.ant.taskdefs.Execute;
  21. import org.apache.tools.ant.types.Commandline;
  22. import org.apache.tools.ant.taskdefs.condition.Os;
  23. /**
  24. * Task to perform mkattr command to ClearCase.
  25. * <p>
  26. * The following attributes are interpreted:
  27. * <table border="1">
  28. * <tr>
  29. * <th>Attribute</th>
  30. * <th>Values</th>
  31. * <th>Required</th>
  32. * </tr>
  33. * <tr>
  34. * <td>viewpath</td>
  35. * <td>Path to the ClearCase view file or directory that the command will operate on</td>
  36. * <td>Yes</td>
  37. * <tr>
  38. * <tr>
  39. * <td>replace</td>
  40. * <td>Replace the value of the attribute if it already exists</td>
  41. * <td>No</td>
  42. * <tr>
  43. * <tr>
  44. * <td>recurse</td>
  45. * <td>Process each subdirectory under viewpath</td>
  46. * <td>No</td>
  47. * <tr>
  48. * <tr>
  49. * <td>version</td>
  50. * <td>Identify a specific version to attach the attribute to</td>
  51. * <td>No</td>
  52. * <tr>
  53. * <tr>
  54. * <td>typename</td>
  55. * <td>Name of the attribute type</td>
  56. * <td>Yes</td>
  57. * <tr>
  58. * <tr>
  59. * <td>typevalue</td>
  60. * <td>Value to attach to the attribute type</td>
  61. * <td>Yes</td>
  62. * <tr>
  63. * <tr>
  64. * <td>comment</td>
  65. * <td>Specify a comment. Only one of comment or cfile may be used.</td>
  66. * <td>No</td>
  67. * <tr>
  68. * <tr>
  69. * <td>commentfile</td>
  70. * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
  71. * <td>No</td>
  72. * <tr>
  73. * <tr>
  74. * <td>failonerr</td>
  75. * <td>Throw an exception if the command fails. Default is true</td>
  76. * <td>No</td>
  77. * <tr>
  78. * </table>
  79. *
  80. */
  81. public class CCMkattr extends ClearCase {
  82. private boolean mReplace = false;
  83. private boolean mRecurse = false;
  84. private String mVersion = null;
  85. private String mTypeName = null;
  86. private String mTypeValue = null;
  87. private String mComment = null;
  88. private String mCfile = null;
  89. /**
  90. * Executes the task.
  91. * <p>
  92. * Builds a command line to execute cleartool and then calls Exec's run method
  93. * to execute the command line.
  94. * @throws BuildException if the command fails and failonerr is set to true
  95. */
  96. public void execute() throws BuildException {
  97. Commandline commandLine = new Commandline();
  98. Project aProj = getProject();
  99. int result = 0;
  100. // Check for required attributes
  101. if (getTypeName() == null) {
  102. throw new BuildException("Required attribute TypeName not specified");
  103. }
  104. if (getTypeValue() == null) {
  105. throw new BuildException("Required attribute TypeValue not specified");
  106. }
  107. // Default the viewpath to basedir if it is not specified
  108. if (getViewPath() == null) {
  109. setViewPath(aProj.getBaseDir().getPath());
  110. }
  111. // build the command line from what we got. the format is
  112. // cleartool mkattr [options...] [viewpath ...]
  113. // as specified in the CLEARTOOL help
  114. commandLine.setExecutable(getClearToolCommand());
  115. commandLine.createArgument().setValue(COMMAND_MKATTR);
  116. checkOptions(commandLine);
  117. if (!getFailOnErr()) {
  118. getProject().log("Ignoring any errors that occur for: "
  119. + getViewPathBasename(), Project.MSG_VERBOSE);
  120. }
  121. // For debugging
  122. // System.out.println(commandLine.toString());
  123. result = run(commandLine);
  124. if (Execute.isFailure(result) && getFailOnErr()) {
  125. String msg = "Failed executing: " + commandLine.toString();
  126. throw new BuildException(msg, getLocation());
  127. }
  128. }
  129. /**
  130. * Check the command line options.
  131. */
  132. private void checkOptions(Commandline cmd) {
  133. if (getReplace()) {
  134. // -replace
  135. cmd.createArgument().setValue(FLAG_REPLACE);
  136. }
  137. if (getRecurse()) {
  138. // -recurse
  139. cmd.createArgument().setValue(FLAG_RECURSE);
  140. }
  141. if (getVersion() != null) {
  142. // -version
  143. getVersionCommand(cmd);
  144. }
  145. if (getComment() != null) {
  146. // -c
  147. getCommentCommand(cmd);
  148. } else {
  149. if (getCommentFile() != null) {
  150. // -cfile
  151. getCommentFileCommand(cmd);
  152. } else {
  153. cmd.createArgument().setValue(FLAG_NOCOMMENT);
  154. }
  155. }
  156. if (getTypeName() != null) {
  157. // type
  158. getTypeCommand(cmd);
  159. }
  160. if (getTypeValue() != null) {
  161. // type value
  162. getTypeValueCommand(cmd);
  163. }
  164. // viewpath
  165. cmd.createArgument().setValue(getViewPath());
  166. }
  167. /**
  168. * Set the replace flag
  169. *
  170. * @param replace the status to set the flag to
  171. */
  172. public void setReplace(boolean replace) {
  173. mReplace = replace;
  174. }
  175. /**
  176. * Get replace flag status
  177. *
  178. * @return boolean containing status of replace flag
  179. */
  180. public boolean getReplace() {
  181. return mReplace;
  182. }
  183. /**
  184. * Set recurse flag
  185. *
  186. * @param recurse the status to set the flag to
  187. */
  188. public void setRecurse(boolean recurse) {
  189. mRecurse = recurse;
  190. }
  191. /**
  192. * Get recurse flag status
  193. *
  194. * @return boolean containing status of recurse flag
  195. */
  196. public boolean getRecurse() {
  197. return mRecurse;
  198. }
  199. /**
  200. * Set the version flag
  201. *
  202. * @param version the status to set the flag to
  203. */
  204. public void setVersion(String version) {
  205. mVersion = version;
  206. }
  207. /**
  208. * Get version flag status
  209. *
  210. * @return boolean containing status of version flag
  211. */
  212. public String getVersion() {
  213. return mVersion;
  214. }
  215. /**
  216. * Set comment string
  217. *
  218. * @param comment the comment string
  219. */
  220. public void setComment(String comment) {
  221. mComment = comment;
  222. }
  223. /**
  224. * Get comment string
  225. *
  226. * @return String containing the comment
  227. */
  228. public String getComment() {
  229. return mComment;
  230. }
  231. /**
  232. * Set comment file
  233. *
  234. * @param cfile the path to the comment file
  235. */
  236. public void setCommentFile(String cfile) {
  237. mCfile = cfile;
  238. }
  239. /**
  240. * Get comment file
  241. *
  242. * @return String containing the path to the comment file
  243. */
  244. public String getCommentFile() {
  245. return mCfile;
  246. }
  247. /**
  248. * Set the attribute type-name
  249. *
  250. * @param tn the type name
  251. */
  252. public void setTypeName(String tn) {
  253. mTypeName = tn;
  254. }
  255. /**
  256. * Get attribute type-name
  257. *
  258. * @return String containing type name
  259. */
  260. public String getTypeName() {
  261. return mTypeName;
  262. }
  263. /**
  264. * Set the attribute type-value
  265. *
  266. * @param tv the type value
  267. */
  268. public void setTypeValue(String tv) {
  269. mTypeValue = tv;
  270. }
  271. /**
  272. * Get the attribute type-value
  273. *
  274. * @return String containing type value
  275. */
  276. public String getTypeValue() {
  277. return mTypeValue;
  278. }
  279. /**
  280. * Get the 'version' command
  281. *
  282. * @param cmd CommandLine containing the command line string with or
  283. * without the version flag and string appended
  284. */
  285. private void getVersionCommand(Commandline cmd) {
  286. if (getVersion() != null) {
  287. /* Had to make two separate commands here because if a space is
  288. inserted between the flag and the value, it is treated as a
  289. Windows filename with a space and it is enclosed in double
  290. quotes ("). This breaks clearcase.
  291. */
  292. cmd.createArgument().setValue(FLAG_VERSION);
  293. cmd.createArgument().setValue(getVersion());
  294. }
  295. }
  296. /**
  297. * Get the 'comment' command
  298. *
  299. * @param cmd containing the command line string with or
  300. * without the comment flag and string appended
  301. */
  302. private void getCommentCommand(Commandline cmd) {
  303. if (getComment() != null) {
  304. /* Had to make two separate commands here because if a space is
  305. inserted between the flag and the value, it is treated as a
  306. Windows filename with a space and it is enclosed in double
  307. quotes ("). This breaks clearcase.
  308. */
  309. cmd.createArgument().setValue(FLAG_COMMENT);
  310. cmd.createArgument().setValue(getComment());
  311. }
  312. }
  313. /**
  314. * Get the 'commentfile' command
  315. *
  316. * @param cmd containing the command line string with or
  317. * without the commentfile flag and file appended
  318. */
  319. private void getCommentFileCommand(Commandline cmd) {
  320. if (getCommentFile() != null) {
  321. /* Had to make two separate commands here because if a space is
  322. inserted between the flag and the value, it is treated as a
  323. Windows filename with a space and it is enclosed in double
  324. quotes ("). This breaks clearcase.
  325. */
  326. cmd.createArgument().setValue(FLAG_COMMENTFILE);
  327. cmd.createArgument().setValue(getCommentFile());
  328. }
  329. }
  330. /**
  331. * Get the attribute type-name
  332. *
  333. * @param cmd containing the command line string with or
  334. * without the type-name
  335. */
  336. private void getTypeCommand(Commandline cmd) {
  337. String typenm = getTypeName();
  338. if (typenm != null) {
  339. cmd.createArgument().setValue(typenm);
  340. }
  341. }
  342. /**
  343. * Get the attribute type-value
  344. *
  345. * @param cmd containing the command line string with or
  346. * without the type-value
  347. */
  348. private void getTypeValueCommand(Commandline cmd) {
  349. String typevl = getTypeValue();
  350. if (typevl != null) {
  351. if (Os.isFamily("windows")) {
  352. typevl = "\\\"" + typevl + "\\\""; // Windows quoting of the value
  353. } else {
  354. typevl = "\"" + typevl + "\"";
  355. }
  356. cmd.createArgument().setValue(typevl);
  357. }
  358. }
  359. /**
  360. * -replace flag -- replace the existing value of the attribute
  361. */
  362. public static final String FLAG_REPLACE = "-replace";
  363. /**
  364. * -recurse flag -- process all subdirectories
  365. */
  366. public static final String FLAG_RECURSE = "-recurse";
  367. /**
  368. * -version flag -- attach attribute to specified version
  369. */
  370. public static final String FLAG_VERSION = "-version";
  371. /**
  372. * -c flag -- comment to attach to the element
  373. */
  374. public static final String FLAG_COMMENT = "-c";
  375. /**
  376. * -cfile flag -- file containing a comment to attach to the file
  377. */
  378. public static final String FLAG_COMMENTFILE = "-cfile";
  379. /**
  380. * -nc flag -- no comment is specified
  381. */
  382. public static final String FLAG_NOCOMMENT = "-nc";
  383. }