1. /*
  2. * Copyright 2002-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.sos;
  18. import java.io.File;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.Project;
  21. import org.apache.tools.ant.Task;
  22. import org.apache.tools.ant.taskdefs.Execute;
  23. import org.apache.tools.ant.taskdefs.LogStreamHandler;
  24. import org.apache.tools.ant.types.Commandline;
  25. import org.apache.tools.ant.types.Path;
  26. /**
  27. * A base class for creating tasks for executing commands on SourceOffSite.
  28. *
  29. * These tasks were inspired by the VSS tasks
  30. *
  31. */
  32. public abstract class SOS extends Task implements SOSCmd {
  33. private String sosCmdDir = null;
  34. private String sosUsername = null;
  35. private String sosPassword = "";
  36. private String projectPath = null;
  37. private String vssServerPath = null;
  38. private String sosServerPath = null;
  39. private String sosHome = null;
  40. private String localPath = null;
  41. private String version = null;
  42. private String label = null;
  43. private String comment = null;
  44. private String filename = null;
  45. private boolean noCompress = false;
  46. private boolean noCache = false;
  47. private boolean recursive = false;
  48. private boolean verbose = false;
  49. /** Commandline to be executed */
  50. protected Commandline commandLine;
  51. /**
  52. * Flag to disable the cache when set.
  53. * Required if SOSHOME is set as an environment variable.
  54. * Defaults to false.
  55. *
  56. * @param nocache True to disable caching.
  57. */
  58. public final void setNoCache(boolean nocache) {
  59. noCache = nocache;
  60. }
  61. /**
  62. * Flag to disable compression when set. Defaults to false.
  63. *
  64. * @param nocompress True to disable compression.
  65. */
  66. public final void setNoCompress(boolean nocompress) {
  67. noCompress = nocompress;
  68. }
  69. /**
  70. * The directory where soscmd(.exe) is located.
  71. * soscmd must be on the path if omitted.
  72. *
  73. * @param dir The new sosCmd value
  74. */
  75. public final void setSosCmd(String dir) {
  76. sosCmdDir = Project.translatePath(dir);
  77. }
  78. /**
  79. * The SourceSafe username.
  80. *
  81. * @param username The new username value
  82. *
  83. * @ant.attribute group="required"
  84. */
  85. public final void setUsername(String username) {
  86. sosUsername = username;
  87. }
  88. /**
  89. * The SourceSafe password.
  90. *
  91. * @param password The new password value
  92. */
  93. public final void setPassword(String password) {
  94. sosPassword = password;
  95. }
  96. /**
  97. * The SourceSafe project path.
  98. *
  99. * @param projectpath The new projectpath value
  100. *
  101. * @ant.attribute group="required"
  102. */
  103. public final void setProjectPath(String projectpath) {
  104. if (projectpath.startsWith(SOSCmd.PROJECT_PREFIX)) {
  105. projectPath = projectpath;
  106. } else {
  107. projectPath = SOSCmd.PROJECT_PREFIX + projectpath;
  108. }
  109. }
  110. /**
  111. * The path to the location of the ss.ini file.
  112. *
  113. * @param vssServerPath The new vssServerPath value
  114. *
  115. * @ant.attribute group="required"
  116. */
  117. public final void setVssServerPath(String vssServerPath) {
  118. this.vssServerPath = vssServerPath;
  119. }
  120. /**
  121. * Path to the SourceOffSite home directory.
  122. *
  123. * @param sosHome The new sosHome value
  124. */
  125. public final void setSosHome(String sosHome) {
  126. this.sosHome = sosHome;
  127. }
  128. /**
  129. * The address and port of SourceOffSite Server,
  130. * for example 192.168.0.1:8888.
  131. *
  132. * @param sosServerPath The new sosServerPath value
  133. *
  134. * @ant.attribute group="required"
  135. */
  136. public final void setSosServerPath(String sosServerPath) {
  137. this.sosServerPath = sosServerPath;
  138. }
  139. /**
  140. * Override the working directory and get to the specified path.
  141. *
  142. * @param path The new localPath value
  143. */
  144. public final void setLocalPath(Path path) {
  145. localPath = path.toString();
  146. }
  147. /**
  148. * Enable verbose output. Defaults to false.
  149. *
  150. * @param verbose True for verbose output.
  151. */
  152. public void setVerbose(boolean verbose) {
  153. this.verbose = verbose;
  154. }
  155. // Special setters for the sub-classes
  156. protected void setInternalFilename(String file) {
  157. filename = file;
  158. }
  159. protected void setInternalRecursive(boolean recurse) {
  160. recursive = recurse;
  161. }
  162. protected void setInternalComment(String text) {
  163. comment = text;
  164. }
  165. protected void setInternalLabel(String text) {
  166. label = text;
  167. }
  168. protected void setInternalVersion(String text) {
  169. version = text;
  170. }
  171. /**
  172. * Get the executable to run. Add the path if it was specifed in the build file
  173. *
  174. * @return the executable to run
  175. */
  176. protected String getSosCommand() {
  177. if (sosCmdDir == null) {
  178. return COMMAND_SOS_EXE;
  179. } else {
  180. return sosCmdDir + File.separator + COMMAND_SOS_EXE;
  181. }
  182. }
  183. /**
  184. * Get the comment
  185. * @return if it was set, null if not
  186. */
  187. protected String getComment() {
  188. return comment;
  189. }
  190. /**
  191. * Get the version
  192. * @return if it was set, null if not
  193. */
  194. protected String getVersion() {
  195. return version;
  196. }
  197. /**
  198. * Get the label
  199. * @return if it was set, null if not
  200. */
  201. protected String getLabel() {
  202. return label;
  203. }
  204. /**
  205. * Get the username
  206. * @return if it was set, null if not
  207. */
  208. protected String getUsername() {
  209. return sosUsername;
  210. }
  211. /**
  212. * Get the password
  213. * @return empty string if it wans't set
  214. */
  215. protected String getPassword() {
  216. return sosPassword;
  217. }
  218. /**
  219. * Get the project path
  220. * @return if it was set, null if not
  221. */
  222. protected String getProjectPath() {
  223. return projectPath;
  224. }
  225. /**
  226. * Get the VSS server path
  227. * @return if it was set, null if not
  228. */
  229. protected String getVssServerPath() {
  230. return vssServerPath;
  231. }
  232. /**
  233. * Get the SOS home directory
  234. * @return if it was set, null if not
  235. */
  236. protected String getSosHome() {
  237. return sosHome;
  238. }
  239. /**
  240. * Get the SOS serve path
  241. * @return if it was set, null if not
  242. */
  243. protected String getSosServerPath() {
  244. return sosServerPath;
  245. }
  246. /**
  247. * Get the filename to be acted upon
  248. * @return if it was set, null if not
  249. */
  250. protected String getFilename() {
  251. return filename;
  252. }
  253. /**
  254. * Get the NoCompress flag
  255. *
  256. * @return the 'nocompress' Flag if the attribute was 'true',
  257. * otherwise an empty string
  258. */
  259. protected String getNoCompress() {
  260. return noCompress ? FLAG_NO_COMPRESSION : "";
  261. }
  262. /**
  263. * Get the NoCache flag
  264. *
  265. * @return the 'nocache' Flag if the attribute was 'true', otherwise an empty string
  266. */
  267. protected String getNoCache() {
  268. return noCache ? FLAG_NO_CACHE : "";
  269. }
  270. /**
  271. * Get the 'verbose' Flag
  272. *
  273. * @return the 'verbose' Flag if the attribute was 'true', otherwise an empty string
  274. */
  275. protected String getVerbose() {
  276. return verbose ? FLAG_VERBOSE : "";
  277. }
  278. /**
  279. * Get the 'recursive' Flag
  280. *
  281. * @return the 'recursive' Flag if the attribute was 'true', otherwise an empty string
  282. */
  283. protected String getRecursive() {
  284. return recursive ? FLAG_RECURSION : "";
  285. }
  286. /**
  287. * Builds and returns the working directory.
  288. * <p>
  289. * The localpath is created if it didn't exist
  290. *
  291. * @return the absolute path of the working directory
  292. */
  293. protected String getLocalPath() {
  294. if (localPath == null) {
  295. return getProject().getBaseDir().getAbsolutePath();
  296. } else {
  297. // make sure localDir exists, create it if it doesn't
  298. File dir = getProject().resolveFile(localPath);
  299. if (!dir.exists()) {
  300. boolean done = dir.mkdirs();
  301. if (!done) {
  302. String msg = "Directory " + localPath + " creation was not "
  303. + "successful for an unknown reason";
  304. throw new BuildException(msg, getLocation());
  305. }
  306. getProject().log("Created dir: " + dir.getAbsolutePath());
  307. }
  308. return dir.getAbsolutePath();
  309. }
  310. }
  311. /**
  312. * Subclasses implement the logic required to construct the command line.
  313. *
  314. * @return The command line to execute.
  315. */
  316. abstract Commandline buildCmdLine();
  317. /**
  318. * Execute the created command line.
  319. *
  320. * @throws BuildException
  321. */
  322. public void execute()
  323. throws BuildException {
  324. int result = 0;
  325. buildCmdLine();
  326. result = run(commandLine);
  327. if (result == 255) { // This is the exit status
  328. String msg = "Failed executing: " + commandLine.toString();
  329. throw new BuildException(msg, getLocation());
  330. }
  331. }
  332. /**
  333. * Execute the created command line.
  334. *
  335. * @param cmd The command line to run.
  336. * @return int the exit code.
  337. * @throws BuildException
  338. */
  339. protected int run(Commandline cmd) {
  340. try {
  341. Execute exe = new Execute(new LogStreamHandler(this,
  342. Project.MSG_INFO,
  343. Project.MSG_WARN));
  344. exe.setAntRun(getProject());
  345. exe.setWorkingDirectory(getProject().getBaseDir());
  346. exe.setCommandline(cmd.getCommandline());
  347. exe.setVMLauncher(false); // Use the OS VM launcher so we get environment variables
  348. return exe.execute();
  349. } catch (java.io.IOException e) {
  350. throw new BuildException(e, getLocation());
  351. }
  352. }
  353. /** Sets the executable and add the required attributes to the command line. */
  354. protected void getRequiredAttributes() {
  355. // Get the path to the soscmd(.exe)
  356. commandLine.setExecutable(getSosCommand());
  357. // SOS server address is required
  358. if (getSosServerPath() == null) {
  359. throw new BuildException("sosserverpath attribute must be set!", getLocation());
  360. }
  361. commandLine.createArgument().setValue(FLAG_SOS_SERVER);
  362. commandLine.createArgument().setValue(getSosServerPath());
  363. // Login info is required
  364. if (getUsername() == null) {
  365. throw new BuildException("username attribute must be set!", getLocation());
  366. }
  367. commandLine.createArgument().setValue(FLAG_USERNAME);
  368. commandLine.createArgument().setValue(getUsername());
  369. // The SOS class knows that the SOS server needs the password flag,
  370. // even if there is no password ,so we send a " "
  371. commandLine.createArgument().setValue(FLAG_PASSWORD);
  372. commandLine.createArgument().setValue(getPassword());
  373. // VSS Info is required
  374. if (getVssServerPath() == null) {
  375. throw new BuildException("vssserverpath attribute must be set!", getLocation());
  376. }
  377. commandLine.createArgument().setValue(FLAG_VSS_SERVER);
  378. commandLine.createArgument().setValue(getVssServerPath());
  379. // VSS project is required
  380. if (getProjectPath() == null) {
  381. throw new BuildException("projectpath attribute must be set!", getLocation());
  382. }
  383. commandLine.createArgument().setValue(FLAG_PROJECT);
  384. commandLine.createArgument().setValue(getProjectPath());
  385. }
  386. /** Adds the optional attributes to the command line. */
  387. protected void getOptionalAttributes() {
  388. // -verbose
  389. commandLine.createArgument().setValue(getVerbose());
  390. // Disable Compression
  391. commandLine.createArgument().setValue(getNoCompress());
  392. // Path to the SourceOffSite home directory /home/user/.sos
  393. if (getSosHome() == null) {
  394. // If -soshome was not specified then we can look for nocache
  395. commandLine.createArgument().setValue(getNoCache());
  396. } else {
  397. commandLine.createArgument().setValue(FLAG_SOS_HOME);
  398. commandLine.createArgument().setValue(getSosHome());
  399. }
  400. //If a working directory was specified then add it to the command line
  401. if (getLocalPath() != null) {
  402. commandLine.createArgument().setValue(FLAG_WORKING_DIR);
  403. commandLine.createArgument().setValue(getLocalPath());
  404. }
  405. }
  406. }