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: package org.apache.tools.ant.taskdefs.optional.sos;
019:
020: import java.io.File;
021: import org.apache.tools.ant.BuildException;
022: import org.apache.tools.ant.Project;
023: import org.apache.tools.ant.Task;
024: import org.apache.tools.ant.taskdefs.Execute;
025: import org.apache.tools.ant.taskdefs.LogStreamHandler;
026: import org.apache.tools.ant.types.Commandline;
027: import org.apache.tools.ant.types.Path;
028: import org.apache.tools.ant.util.FileUtils;
029:
030: /**
031: * A base class for creating tasks for executing commands on SourceOffSite.
032: *
033: * These tasks were inspired by the VSS tasks.
034: *
035: */
036:
037: public abstract class SOS extends Task implements SOSCmd {
038:
039: private String sosCmdDir = null;
040: private String sosUsername = null;
041: private String sosPassword = "";
042: private String projectPath = null;
043: private String vssServerPath = null;
044: private String sosServerPath = null;
045: private String sosHome = null;
046: private String localPath = null;
047: private String version = null;
048: private String label = null;
049: private String comment = null;
050: private String filename = null;
051:
052: private boolean noCompress = false;
053: private boolean noCache = false;
054: private boolean recursive = false;
055: private boolean verbose = false;
056:
057: // CheckStyle:VisibilityModifier OFF - bc
058: /** Commandline to be executed. */
059: protected Commandline commandLine;
060:
061: // CheckStyle:VisibilityModifier ON
062:
063: /**
064: * Flag to disable the cache when set.
065: * Required if SOSHOME is set as an environment variable.
066: * Defaults to false.
067: *
068: * @param nocache True to disable caching.
069: */
070: public final void setNoCache(boolean nocache) {
071: noCache = nocache;
072: }
073:
074: /**
075: * Flag to disable compression when set. Defaults to false.
076: *
077: * @param nocompress True to disable compression.
078: */
079: public final void setNoCompress(boolean nocompress) {
080: noCompress = nocompress;
081: }
082:
083: /**
084: * The directory where soscmd(.exe) is located.
085: * soscmd must be on the path if omitted.
086: *
087: * @param dir The new sosCmd value.
088: */
089: public final void setSosCmd(String dir) {
090: sosCmdDir = FileUtils.translatePath(dir);
091: }
092:
093: /**
094: * The SourceSafe username.
095: *
096: * @param username The new username value.
097: *
098: * @ant.attribute group="required"
099: */
100: public final void setUsername(String username) {
101: sosUsername = username;
102: }
103:
104: /**
105: * The SourceSafe password.
106: *
107: * @param password The new password value.
108: */
109: public final void setPassword(String password) {
110: sosPassword = password;
111: }
112:
113: /**
114: * The SourceSafe project path.
115: *
116: * @param projectpath The new projectpath value.
117: *
118: * @ant.attribute group="required"
119: */
120: public final void setProjectPath(String projectpath) {
121: if (projectpath.startsWith(SOSCmd.PROJECT_PREFIX)) {
122: projectPath = projectpath;
123: } else {
124: projectPath = SOSCmd.PROJECT_PREFIX + projectpath;
125: }
126: }
127:
128: /**
129: * The path to the location of the ss.ini file.
130: *
131: * @param vssServerPath The new vssServerPath value.
132: *
133: * @ant.attribute group="required"
134: */
135: public final void setVssServerPath(String vssServerPath) {
136: this .vssServerPath = vssServerPath;
137: }
138:
139: /**
140: * Path to the SourceOffSite home directory.
141: *
142: * @param sosHome The new sosHome value.
143: */
144: public final void setSosHome(String sosHome) {
145: this .sosHome = sosHome;
146: }
147:
148: /**
149: * The address and port of SourceOffSite Server,
150: * for example 192.168.0.1:8888.
151: *
152: * @param sosServerPath The new sosServerPath value.
153: *
154: * @ant.attribute group="required"
155: */
156: public final void setSosServerPath(String sosServerPath) {
157: this .sosServerPath = sosServerPath;
158: }
159:
160: /**
161: * Override the working directory and get to the specified path.
162: *
163: * @param path The new localPath value.
164: */
165: public final void setLocalPath(Path path) {
166: localPath = path.toString();
167: }
168:
169: /**
170: * Enable verbose output. Defaults to false.
171: *
172: * @param verbose True for verbose output.
173: */
174: public void setVerbose(boolean verbose) {
175: this .verbose = verbose;
176: }
177:
178: // Special setters for the sub-classes
179:
180: /**
181: * Set the file name.
182: * @param file the filename to use.
183: */
184: protected void setInternalFilename(String file) {
185: filename = file;
186: }
187:
188: /**
189: * Set the recursive flag.
190: * @param recurse if true use the recursive flag on the command line.
191: */
192: protected void setInternalRecursive(boolean recurse) {
193: recursive = recurse;
194: }
195:
196: /**
197: * Set the comment text.
198: * @param text the comment text to use.
199: */
200: protected void setInternalComment(String text) {
201: comment = text;
202: }
203:
204: /**
205: * Set the label.
206: * @param text the label to use.
207: */
208: protected void setInternalLabel(String text) {
209: label = text;
210: }
211:
212: /**
213: * Set the version.
214: * @param text the version to use.
215: */
216: protected void setInternalVersion(String text) {
217: version = text;
218: }
219:
220: /**
221: * Get the executable to run. Add the path if it was specifed in the build file
222: *
223: * @return the executable to run.
224: */
225: protected String getSosCommand() {
226: if (sosCmdDir == null) {
227: return COMMAND_SOS_EXE;
228: } else {
229: return sosCmdDir + File.separator + COMMAND_SOS_EXE;
230: }
231: }
232:
233: /**
234: * Get the comment
235: * @return if it was set, null if not.
236: */
237: protected String getComment() {
238: return comment;
239: }
240:
241: /**
242: * Get the version
243: * @return if it was set, null if not.
244: */
245: protected String getVersion() {
246: return version;
247: }
248:
249: /**
250: * Get the label
251: * @return if it was set, null if not.
252: */
253: protected String getLabel() {
254: return label;
255: }
256:
257: /**
258: * Get the username
259: * @return if it was set, null if not.
260: */
261: protected String getUsername() {
262: return sosUsername;
263: }
264:
265: /**
266: * Get the password
267: * @return empty string if it wasn't set.
268: */
269: protected String getPassword() {
270: return sosPassword;
271: }
272:
273: /**
274: * Get the project path
275: * @return if it was set, null if not.
276: */
277: protected String getProjectPath() {
278: return projectPath;
279: }
280:
281: /**
282: * Get the VSS server path
283: * @return if it was set, null if not.
284: */
285: protected String getVssServerPath() {
286: return vssServerPath;
287: }
288:
289: /**
290: * Get the SOS home directory.
291: * @return if it was set, null if not.
292: */
293: protected String getSosHome() {
294: return sosHome;
295: }
296:
297: /**
298: * Get the SOS serve path.
299: * @return if it was set, null if not.
300: */
301: protected String getSosServerPath() {
302: return sosServerPath;
303: }
304:
305: /**
306: * Get the filename to be acted upon.
307: * @return if it was set, null if not.
308: */
309: protected String getFilename() {
310: return filename;
311: }
312:
313: /**
314: * Get the NoCompress flag.
315: *
316: * @return the 'nocompress' Flag if the attribute was 'true',
317: * otherwise an empty string.
318: */
319: protected String getNoCompress() {
320: return noCompress ? FLAG_NO_COMPRESSION : "";
321: }
322:
323: /**
324: * Get the NoCache flag.
325: *
326: * @return the 'nocache' Flag if the attribute was 'true', otherwise an empty string.
327: */
328: protected String getNoCache() {
329: return noCache ? FLAG_NO_CACHE : "";
330: }
331:
332: /**
333: * Get the 'verbose' Flag.
334: *
335: * @return the 'verbose' Flag if the attribute was 'true', otherwise an empty string.
336: */
337: protected String getVerbose() {
338: return verbose ? FLAG_VERBOSE : "";
339: }
340:
341: /**
342: * Get the 'recursive' Flag.
343: *
344: * @return the 'recursive' Flag if the attribute was 'true', otherwise an empty string.
345: */
346: protected String getRecursive() {
347: return recursive ? FLAG_RECURSION : "";
348: }
349:
350: /**
351: * Builds and returns the working directory.
352: * <p>
353: * The localpath is created if it didn't exist.
354: *
355: * @return the absolute path of the working directory.
356: */
357: protected String getLocalPath() {
358: if (localPath == null) {
359: return getProject().getBaseDir().getAbsolutePath();
360: } else {
361: // make sure localDir exists, create it if it doesn't
362: File dir = getProject().resolveFile(localPath);
363: if (!dir.exists()) {
364: boolean done = dir.mkdirs();
365: if (!done) {
366: String msg = "Directory " + localPath
367: + " creation was not "
368: + "successful for an unknown reason";
369: throw new BuildException(msg, getLocation());
370: }
371: getProject().log(
372: "Created dir: " + dir.getAbsolutePath());
373: }
374: return dir.getAbsolutePath();
375: }
376: }
377:
378: /**
379: * Subclasses implement the logic required to construct the command line.
380: *
381: * @return The command line to execute.
382: */
383: abstract Commandline buildCmdLine();
384:
385: /**
386: * Execute the created command line.
387: *
388: * @throws BuildException on error.
389: */
390: public void execute() throws BuildException {
391: int result = 0;
392: buildCmdLine();
393: result = run(commandLine);
394: if (result == 255) { // This is the exit status
395: String msg = "Failed executing: " + commandLine.toString();
396: throw new BuildException(msg, getLocation());
397: }
398: }
399:
400: /**
401: * Execute the created command line.
402: *
403: * @param cmd The command line to run.
404: * @return int the exit code.
405: * @throws BuildException
406: */
407: protected int run(Commandline cmd) {
408: try {
409: Execute exe = new Execute(new LogStreamHandler(this ,
410: Project.MSG_INFO, Project.MSG_WARN));
411:
412: exe.setAntRun(getProject());
413: exe.setWorkingDirectory(getProject().getBaseDir());
414: exe.setCommandline(cmd.getCommandline());
415: exe.setVMLauncher(false); // Use the OS VM launcher so we get environment variables
416: return exe.execute();
417: } catch (java.io.IOException e) {
418: throw new BuildException(e, getLocation());
419: }
420: }
421:
422: /** Sets the executable and add the required attributes to the command line. */
423: protected void getRequiredAttributes() {
424: // Get the path to the soscmd(.exe)
425: commandLine.setExecutable(getSosCommand());
426: // SOS server address is required
427: if (getSosServerPath() == null) {
428: throw new BuildException(
429: "sosserverpath attribute must be set!",
430: getLocation());
431: }
432: commandLine.createArgument().setValue(FLAG_SOS_SERVER);
433: commandLine.createArgument().setValue(getSosServerPath());
434: // Login info is required
435: if (getUsername() == null) {
436: throw new BuildException("username attribute must be set!",
437: getLocation());
438: }
439: commandLine.createArgument().setValue(FLAG_USERNAME);
440: commandLine.createArgument().setValue(getUsername());
441: // The SOS class knows that the SOS server needs the password flag,
442: // even if there is no password ,so we send a " "
443: commandLine.createArgument().setValue(FLAG_PASSWORD);
444: commandLine.createArgument().setValue(getPassword());
445: // VSS Info is required
446: if (getVssServerPath() == null) {
447: throw new BuildException(
448: "vssserverpath attribute must be set!",
449: getLocation());
450: }
451: commandLine.createArgument().setValue(FLAG_VSS_SERVER);
452: commandLine.createArgument().setValue(getVssServerPath());
453: // VSS project is required
454: if (getProjectPath() == null) {
455: throw new BuildException(
456: "projectpath attribute must be set!", getLocation());
457: }
458: commandLine.createArgument().setValue(FLAG_PROJECT);
459: commandLine.createArgument().setValue(getProjectPath());
460: }
461:
462: /** Adds the optional attributes to the command line. */
463: protected void getOptionalAttributes() {
464: // -verbose
465: commandLine.createArgument().setValue(getVerbose());
466: // Disable Compression
467: commandLine.createArgument().setValue(getNoCompress());
468: // Path to the SourceOffSite home directory /home/user/.sos
469: if (getSosHome() == null) {
470: // If -soshome was not specified then we can look for nocache
471: commandLine.createArgument().setValue(getNoCache());
472: } else {
473: commandLine.createArgument().setValue(FLAG_SOS_HOME);
474: commandLine.createArgument().setValue(getSosHome());
475: }
476: //If a working directory was specified then add it to the command line
477: if (getLocalPath() != null) {
478: commandLine.createArgument().setValue(FLAG_WORKING_DIR);
479: commandLine.createArgument().setValue(getLocalPath());
480: }
481: }
482: }
|