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 | package org.apache.tools.ant.taskdefs.optional.vss;
|
---|
19 |
|
---|
20 | import org.apache.tools.ant.types.EnumeratedAttribute;
|
---|
21 | import java.io.File;
|
---|
22 | import java.io.IOException;
|
---|
23 | import java.text.DateFormat;
|
---|
24 | import java.text.ParseException;
|
---|
25 | import java.util.Calendar;
|
---|
26 | import java.util.Date;
|
---|
27 | import java.util.GregorianCalendar;
|
---|
28 |
|
---|
29 | import org.apache.tools.ant.BuildException;
|
---|
30 | import org.apache.tools.ant.Project;
|
---|
31 | import org.apache.tools.ant.Task;
|
---|
32 | import org.apache.tools.ant.taskdefs.Execute;
|
---|
33 | import org.apache.tools.ant.taskdefs.LogStreamHandler;
|
---|
34 | import org.apache.tools.ant.types.Commandline;
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * A base class for creating tasks for executing commands on Visual SourceSafe.
|
---|
38 | * <p>
|
---|
39 | * The class extends the 'exec' task as it operates by executing the ss.exe program
|
---|
40 | * supplied with SourceSafe. By default the task expects ss.exe to be in the path,
|
---|
41 | * you can override this be specifying the ssdir attribute.
|
---|
42 | * </p>
|
---|
43 | * <p>
|
---|
44 | * This class provides set and get methods for 'login' and 'vsspath' attributes. It
|
---|
45 | * also contains constants for the flags that can be passed to SS.
|
---|
46 | * </p>
|
---|
47 | *
|
---|
48 | */
|
---|
49 | public abstract class MSVSS extends Task implements MSVSSConstants {
|
---|
50 |
|
---|
51 | private String ssDir = null;
|
---|
52 | private String vssLogin = null;
|
---|
53 | private String vssPath = null;
|
---|
54 | private String serverPath = null;
|
---|
55 |
|
---|
56 | /** Version */
|
---|
57 | private String version = null;
|
---|
58 | /** Date */
|
---|
59 | private String date = null;
|
---|
60 | /** Label */
|
---|
61 | private String label = null;
|
---|
62 | /** Auto response */
|
---|
63 | private String autoResponse = null;
|
---|
64 | /** Local path */
|
---|
65 | private String localPath = null;
|
---|
66 | /** Comment */
|
---|
67 | private String comment = null;
|
---|
68 | /** From label */
|
---|
69 | private String fromLabel = null;
|
---|
70 | /** To label */
|
---|
71 | private String toLabel = null;
|
---|
72 | /** Output file name */
|
---|
73 | private String outputFileName = null;
|
---|
74 | /** User */
|
---|
75 | private String user = null;
|
---|
76 | /** From date */
|
---|
77 | private String fromDate = null;
|
---|
78 | /** To date */
|
---|
79 | private String toDate = null;
|
---|
80 | /** History style */
|
---|
81 | private String style = null;
|
---|
82 | /** Quiet defaults to false */
|
---|
83 | private boolean quiet = false;
|
---|
84 | /** Recursive defaults to false */
|
---|
85 | private boolean recursive = false;
|
---|
86 | /** Writable defaults to false */
|
---|
87 | private boolean writable = false;
|
---|
88 | /** Fail on error defaults to true */
|
---|
89 | private boolean failOnError = true;
|
---|
90 | /** Get local copy for checkout defaults to true */
|
---|
91 | private boolean getLocalCopy = true;
|
---|
92 | /** Number of days offset for History */
|
---|
93 | private int numDays = Integer.MIN_VALUE;
|
---|
94 | /** Date format for History */
|
---|
95 | private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
|
---|
96 | /** Timestamp for retreived files */
|
---|
97 | private CurrentModUpdated timestamp = null;
|
---|
98 | /** Behaviour for writable files */
|
---|
99 | private WritableFiles writableFiles = null;
|
---|
100 |
|
---|
101 | /**
|
---|
102 | * Each sub-class must implemnt this method and return the constructed
|
---|
103 | * command line to be executed. It is up to the sub-task to determine the
|
---|
104 | * required attrubutes and their order.
|
---|
105 | * @return The Constructed command line.
|
---|
106 | */
|
---|
107 | abstract Commandline buildCmdLine();
|
---|
108 |
|
---|
109 | /**
|
---|
110 | * Directory where <code>ss.exe</code> resides.
|
---|
111 | * By default the task expects it to be in the PATH.
|
---|
112 | * @param dir The directory containing ss.exe.
|
---|
113 | */
|
---|
114 | public final void setSsdir(String dir) {
|
---|
115 | this.ssDir = Project.translatePath(dir);
|
---|
116 | }
|
---|
117 |
|
---|
118 | /**
|
---|
119 | * Login to use when accessing VSS, formatted as "username,password".
|
---|
120 | * <p>
|
---|
121 | * You can omit the password if your database is not password protected.
|
---|
122 | * If you have a password and omit it, Ant will hang.
|
---|
123 | * @param vssLogin The login string to use.
|
---|
124 | */
|
---|
125 | public final void setLogin(final String vssLogin) {
|
---|
126 | this.vssLogin = vssLogin;
|
---|
127 | }
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * SourceSafe path which specifies the project/file(s) you wish to perform
|
---|
131 | * the action on.
|
---|
132 | * <p>
|
---|
133 | * A prefix of 'vss://' will be removed if specified.
|
---|
134 | * @param vssPath The VSS project path.
|
---|
135 | * @ant.attribute group="required"
|
---|
136 | */
|
---|
137 | public final void setVsspath(final String vssPath) {
|
---|
138 | String projectPath;
|
---|
139 | if (vssPath.startsWith("vss://")) { //$NON-NLS-1$
|
---|
140 | projectPath = vssPath.substring(5);
|
---|
141 | } else {
|
---|
142 | projectPath = vssPath;
|
---|
143 | }
|
---|
144 |
|
---|
145 | if (projectPath.startsWith(PROJECT_PREFIX)) {
|
---|
146 | this.vssPath = projectPath;
|
---|
147 | } else {
|
---|
148 | this.vssPath = PROJECT_PREFIX + projectPath;
|
---|
149 | }
|
---|
150 | }
|
---|
151 |
|
---|
152 | /**
|
---|
153 | * Directory where <code>srssafe.ini</code> resides.
|
---|
154 | * @param serverPath The path to the VSS server.
|
---|
155 | */
|
---|
156 | public final void setServerpath(final String serverPath) {
|
---|
157 | this.serverPath = serverPath;
|
---|
158 | }
|
---|
159 |
|
---|
160 | /**
|
---|
161 | * Indicates if the build should fail if the Sourcesafe command does. Defaults to true.
|
---|
162 | * @param failOnError True if task should fail on any error.
|
---|
163 | */
|
---|
164 | public final void setFailOnError(final boolean failOnError) {
|
---|
165 | this.failOnError = failOnError;
|
---|
166 | }
|
---|
167 |
|
---|
168 | /**
|
---|
169 | * Executes the task. <br>
|
---|
170 | * Builds a command line to execute ss.exe and then calls Exec's run method
|
---|
171 | * to execute the command line.
|
---|
172 | * @throws BuildException if the command cannot execute.
|
---|
173 | */
|
---|
174 | public void execute() throws BuildException {
|
---|
175 | int result = 0;
|
---|
176 | Commandline commandLine = buildCmdLine();
|
---|
177 | result = run(commandLine);
|
---|
178 | if (Execute.isFailure(result) && getFailOnError()) {
|
---|
179 | String msg = "Failed executing: " + formatCommandLine(commandLine)
|
---|
180 | + " With a return code of " + result;
|
---|
181 | throw new BuildException(msg, getLocation());
|
---|
182 | }
|
---|
183 | }
|
---|
184 |
|
---|
185 | // Special setters for the sub-classes
|
---|
186 |
|
---|
187 | protected void setInternalComment(final String comment) {
|
---|
188 | this.comment = comment;
|
---|
189 | }
|
---|
190 |
|
---|
191 | protected void setInternalAutoResponse(final String autoResponse) {
|
---|
192 | this.autoResponse = autoResponse;
|
---|
193 | }
|
---|
194 |
|
---|
195 | protected void setInternalDate(final String date) {
|
---|
196 | this.date = date;
|
---|
197 | }
|
---|
198 |
|
---|
199 | protected void setInternalDateFormat(final DateFormat dateFormat) {
|
---|
200 | this.dateFormat = dateFormat;
|
---|
201 | }
|
---|
202 |
|
---|
203 | protected void setInternalFailOnError(final boolean failOnError) {
|
---|
204 | this.failOnError = failOnError;
|
---|
205 | }
|
---|
206 |
|
---|
207 | protected void setInternalFromDate(final String fromDate) {
|
---|
208 | this.fromDate = fromDate;
|
---|
209 | }
|
---|
210 |
|
---|
211 | protected void setInternalFromLabel(final String fromLabel) {
|
---|
212 | this.fromLabel = fromLabel;
|
---|
213 | }
|
---|
214 |
|
---|
215 | protected void setInternalLabel(final String label) {
|
---|
216 | this.label = label;
|
---|
217 | }
|
---|
218 |
|
---|
219 | protected void setInternalLocalPath(final String localPath) {
|
---|
220 | this.localPath = localPath;
|
---|
221 | }
|
---|
222 |
|
---|
223 | protected void setInternalNumDays(final int numDays) {
|
---|
224 | this.numDays = numDays;
|
---|
225 | }
|
---|
226 |
|
---|
227 | protected void setInternalOutputFilename(final String outputFileName) {
|
---|
228 | this.outputFileName = outputFileName;
|
---|
229 | }
|
---|
230 |
|
---|
231 | protected void setInternalQuiet(final boolean quiet) {
|
---|
232 | this.quiet = quiet;
|
---|
233 | }
|
---|
234 |
|
---|
235 | protected void setInternalRecursive(final boolean recursive) {
|
---|
236 | this.recursive = recursive;
|
---|
237 | }
|
---|
238 |
|
---|
239 | protected void setInternalStyle(final String style) {
|
---|
240 | this.style = style;
|
---|
241 | }
|
---|
242 |
|
---|
243 | protected void setInternalToDate(final String toDate) {
|
---|
244 | this.toDate = toDate;
|
---|
245 | }
|
---|
246 |
|
---|
247 | protected void setInternalToLabel(final String toLabel) {
|
---|
248 | this.toLabel = toLabel;
|
---|
249 | }
|
---|
250 |
|
---|
251 | protected void setInternalUser(final String user) {
|
---|
252 | this.user = user;
|
---|
253 | }
|
---|
254 |
|
---|
255 | protected void setInternalVersion(final String version) {
|
---|
256 | this.version = version;
|
---|
257 | }
|
---|
258 |
|
---|
259 | protected void setInternalWritable(final boolean writable) {
|
---|
260 | this.writable = writable;
|
---|
261 | }
|
---|
262 |
|
---|
263 | protected void setInternalFileTimeStamp(final CurrentModUpdated timestamp) {
|
---|
264 | this.timestamp = timestamp;
|
---|
265 | }
|
---|
266 |
|
---|
267 | protected void setInternalWritableFiles(final WritableFiles writableFiles) {
|
---|
268 | this.writableFiles = writableFiles;
|
---|
269 | }
|
---|
270 |
|
---|
271 | protected void setInternalGetLocalCopy(final boolean getLocalCopy) {
|
---|
272 | this.getLocalCopy = getLocalCopy;
|
---|
273 | }
|
---|
274 |
|
---|
275 | /**
|
---|
276 | * Gets the sscommand string. "ss" or "c:\path\to\ss"
|
---|
277 | * @return The path to ss.exe or just ss if sscommand is not set.
|
---|
278 | */
|
---|
279 | protected String getSSCommand() {
|
---|
280 | if (ssDir == null) {
|
---|
281 | return SS_EXE;
|
---|
282 | }
|
---|
283 | return ssDir.endsWith(File.separator) ? ssDir + SS_EXE : ssDir
|
---|
284 | + File.separator + SS_EXE;
|
---|
285 | }
|
---|
286 |
|
---|
287 | /**
|
---|
288 | * Gets the vssserverpath string.
|
---|
289 | * @return null if vssserverpath is not set.
|
---|
290 | */
|
---|
291 | protected String getVsspath() {
|
---|
292 | return vssPath;
|
---|
293 | }
|
---|
294 |
|
---|
295 | /**
|
---|
296 | * Gets the quiet string. -O-
|
---|
297 | * @return An empty string if quiet is not set or is false.
|
---|
298 | */
|
---|
299 | protected String getQuiet() {
|
---|
300 | return quiet ? FLAG_QUIET : "";
|
---|
301 | }
|
---|
302 |
|
---|
303 | /**
|
---|
304 | * Gets the recursive string. "-R"
|
---|
305 | * @return An empty string if recursive is not set or is false.
|
---|
306 | */
|
---|
307 | protected String getRecursive() {
|
---|
308 | return recursive ? FLAG_RECURSION : "";
|
---|
309 | }
|
---|
310 |
|
---|
311 | /**
|
---|
312 | * Gets the writable string. "-W"
|
---|
313 | * @return An empty string if writable is not set or is false.
|
---|
314 | */
|
---|
315 | protected String getWritable() {
|
---|
316 | return writable ? FLAG_WRITABLE : "";
|
---|
317 | }
|
---|
318 |
|
---|
319 | /**
|
---|
320 | * Gets the label string. "-Lbuild1"
|
---|
321 | * Max label length is 32 chars
|
---|
322 | * @return An empty string if label is not set.
|
---|
323 | */
|
---|
324 | protected String getLabel() {
|
---|
325 | String shortLabel="";
|
---|
326 | if (label != null && label.length() > 0) {
|
---|
327 | shortLabel = FLAG_LABEL + getShortLabel();
|
---|
328 | }
|
---|
329 | return shortLabel;
|
---|
330 | }
|
---|
331 | /**
|
---|
332 | * Return at most the 30 first chars of the label, logging a warning message about the truncation
|
---|
333 | * @return at most the 30 first chars of the label
|
---|
334 | */
|
---|
335 | private String getShortLabel() {
|
---|
336 | String shortLabel;
|
---|
337 | if (label != null && label.length() > 31) {
|
---|
338 | shortLabel = this.label.substring(0, 30);
|
---|
339 | log("Label is longer than 31 characters, truncated to: " + shortLabel, Project.MSG_WARN);
|
---|
340 | } else {
|
---|
341 | shortLabel = label;
|
---|
342 | }
|
---|
343 | return shortLabel;
|
---|
344 | }
|
---|
345 | /**
|
---|
346 | * Gets the style string. "-Lbuild1"
|
---|
347 | * @return An empty string if label is not set.
|
---|
348 | */
|
---|
349 | protected String getStyle() {
|
---|
350 | return style != null ? style : "";
|
---|
351 | }
|
---|
352 |
|
---|
353 | /**
|
---|
354 | * Gets the version string. Returns the first specified of version "-V1.0",
|
---|
355 | * date "-Vd01.01.01", label "-Vlbuild1".
|
---|
356 | * @return An empty string if a version, date and label are not set.
|
---|
357 | */
|
---|
358 | protected String getVersionDateLabel() {
|
---|
359 | String versionDateLabel = "";
|
---|
360 | if (version != null) {
|
---|
361 | versionDateLabel = FLAG_VERSION + version;
|
---|
362 | } else if (date != null) {
|
---|
363 | versionDateLabel = FLAG_VERSION_DATE + date;
|
---|
364 | } else {
|
---|
365 | // Use getShortLabel() so labels longer then 30 char are truncated
|
---|
366 | // and the user is warned
|
---|
367 | String shortLabel = getShortLabel();
|
---|
368 | if (shortLabel != null && !shortLabel.equals("")) {
|
---|
369 | versionDateLabel = FLAG_VERSION_LABEL + shortLabel;
|
---|
370 | }
|
---|
371 | }
|
---|
372 | return versionDateLabel;
|
---|
373 | }
|
---|
374 |
|
---|
375 | /**
|
---|
376 | * Gets the version string.
|
---|
377 | * @return An empty string if a version is not set.
|
---|
378 | */
|
---|
379 | protected String getVersion() {
|
---|
380 | return version != null ? FLAG_VERSION + version : "";
|
---|
381 | }
|
---|
382 |
|
---|
383 | /**
|
---|
384 | * Gets the localpath string. "-GLc:\source" <p>
|
---|
385 | * The localpath is created if it didn't exist.
|
---|
386 | * @return An empty string if localpath is not set.
|
---|
387 | */
|
---|
388 | protected String getLocalpath() {
|
---|
389 | String lclPath = ""; //set to empty str if no local path return
|
---|
390 | if (localPath != null) {
|
---|
391 | //make sure m_LocalDir exists, create it if it doesn't
|
---|
392 | File dir = getProject().resolveFile(localPath);
|
---|
393 | if (!dir.exists()) {
|
---|
394 | boolean done = dir.mkdirs();
|
---|
395 | if (!done) {
|
---|
396 | String msg = "Directory " + localPath + " creation was not "
|
---|
397 | + "successful for an unknown reason";
|
---|
398 | throw new BuildException(msg, getLocation());
|
---|
399 | }
|
---|
400 | getProject().log("Created dir: " + dir.getAbsolutePath());
|
---|
401 | }
|
---|
402 | lclPath = FLAG_OVERRIDE_WORKING_DIR + localPath;
|
---|
403 | }
|
---|
404 | return lclPath;
|
---|
405 | }
|
---|
406 |
|
---|
407 | /**
|
---|
408 | * Gets the comment string. "-Ccomment text"
|
---|
409 | * @return A comment of "-" if comment is not set.
|
---|
410 | */
|
---|
411 | protected String getComment() {
|
---|
412 | return comment != null ? FLAG_COMMENT + comment : FLAG_COMMENT + "-";
|
---|
413 | }
|
---|
414 |
|
---|
415 | /**
|
---|
416 | * Gets the auto response string. This can be Y "-I-Y" or N "-I-N".
|
---|
417 | * @return The default value "-I-" if autoresponse is not set.
|
---|
418 | */
|
---|
419 | protected String getAutoresponse() {
|
---|
420 | if (autoResponse == null) {
|
---|
421 | return FLAG_AUTORESPONSE_DEF;
|
---|
422 | } else if (autoResponse.equalsIgnoreCase("Y")) {
|
---|
423 | return FLAG_AUTORESPONSE_YES;
|
---|
424 | } else if (autoResponse.equalsIgnoreCase("N")) {
|
---|
425 | return FLAG_AUTORESPONSE_NO;
|
---|
426 | } else {
|
---|
427 | return FLAG_AUTORESPONSE_DEF;
|
---|
428 | }
|
---|
429 | }
|
---|
430 |
|
---|
431 | /**
|
---|
432 | * Gets the login string. This can be user and password, "-Yuser,password"
|
---|
433 | * or just user "-Yuser".
|
---|
434 | * @return An empty string if login is not set.
|
---|
435 | */
|
---|
436 | protected String getLogin() {
|
---|
437 | return vssLogin != null ? FLAG_LOGIN + vssLogin : "";
|
---|
438 | }
|
---|
439 |
|
---|
440 | /**
|
---|
441 | * Gets the output file string. "-Ooutput.file"
|
---|
442 | * @return An empty string if user is not set.
|
---|
443 | */
|
---|
444 | protected String getOutput() {
|
---|
445 | return outputFileName != null ? FLAG_OUTPUT + outputFileName : "";
|
---|
446 | }
|
---|
447 |
|
---|
448 | /**
|
---|
449 | * Gets the user string. "-Uusername"
|
---|
450 | * @return An empty string if user is not set.
|
---|
451 | */
|
---|
452 | protected String getUser() {
|
---|
453 | return user != null ? FLAG_USER + user : "";
|
---|
454 | }
|
---|
455 |
|
---|
456 | /**
|
---|
457 | * Gets the version string. This can be to-from "-VLbuild2~Lbuild1", from
|
---|
458 | * "~Lbuild1" or to "-VLbuild2".
|
---|
459 | * @return An empty string if neither tolabel or fromlabel are set.
|
---|
460 | */
|
---|
461 | protected String getVersionLabel() {
|
---|
462 | if (fromLabel == null && toLabel == null) {
|
---|
463 | return "";
|
---|
464 | }
|
---|
465 | if (fromLabel != null && toLabel != null) {
|
---|
466 | if (fromLabel.length() > 31) {
|
---|
467 | fromLabel = fromLabel.substring(0, 30);
|
---|
468 | log("FromLabel is longer than 31 characters, truncated to: "
|
---|
469 | + fromLabel, Project.MSG_WARN);
|
---|
470 | }
|
---|
471 | if (toLabel.length() > 31) {
|
---|
472 | toLabel = toLabel.substring(0, 30);
|
---|
473 | log("ToLabel is longer than 31 characters, truncated to: "
|
---|
474 | + toLabel, Project.MSG_WARN);
|
---|
475 | }
|
---|
476 | return FLAG_VERSION_LABEL + toLabel + VALUE_FROMLABEL + fromLabel;
|
---|
477 | } else if (fromLabel != null) {
|
---|
478 | if (fromLabel.length() > 31) {
|
---|
479 | fromLabel = fromLabel.substring(0, 30);
|
---|
480 | log("FromLabel is longer than 31 characters, truncated to: "
|
---|
481 | + fromLabel, Project.MSG_WARN);
|
---|
482 | }
|
---|
483 | return FLAG_VERSION + VALUE_FROMLABEL + fromLabel;
|
---|
484 | } else {
|
---|
485 | if (toLabel.length() > 31) {
|
---|
486 | toLabel = toLabel.substring(0, 30);
|
---|
487 | log("ToLabel is longer than 31 characters, truncated to: "
|
---|
488 | + toLabel, Project.MSG_WARN);
|
---|
489 | }
|
---|
490 | return FLAG_VERSION_LABEL + toLabel;
|
---|
491 | }
|
---|
492 | }
|
---|
493 |
|
---|
494 | /**
|
---|
495 | * Gets the Version date string.
|
---|
496 | * @return An empty string if neither Todate or from date are set.
|
---|
497 | * @throws BuildException
|
---|
498 | */
|
---|
499 | protected String getVersionDate() throws BuildException {
|
---|
500 | if (fromDate == null && toDate == null
|
---|
501 | && numDays == Integer.MIN_VALUE) {
|
---|
502 | return "";
|
---|
503 | }
|
---|
504 | if (fromDate != null && toDate != null) {
|
---|
505 | return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE + fromDate;
|
---|
506 | } else if (toDate != null && numDays != Integer.MIN_VALUE) {
|
---|
507 | try {
|
---|
508 | return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE
|
---|
509 | + calcDate(toDate, numDays);
|
---|
510 | } catch (ParseException ex) {
|
---|
511 | String msg = "Error parsing date: " + toDate;
|
---|
512 | throw new BuildException(msg, getLocation());
|
---|
513 | }
|
---|
514 | } else if (fromDate != null && numDays != Integer.MIN_VALUE) {
|
---|
515 | try {
|
---|
516 | return FLAG_VERSION_DATE + calcDate(fromDate, numDays)
|
---|
517 | + VALUE_FROMDATE + fromDate;
|
---|
518 | } catch (ParseException ex) {
|
---|
519 | String msg = "Error parsing date: " + fromDate;
|
---|
520 | throw new BuildException(msg, getLocation());
|
---|
521 | }
|
---|
522 | } else {
|
---|
523 | return fromDate != null ? FLAG_VERSION + VALUE_FROMDATE
|
---|
524 | + fromDate : FLAG_VERSION_DATE + toDate;
|
---|
525 | }
|
---|
526 | }
|
---|
527 |
|
---|
528 | /**
|
---|
529 | * Builds and returns the -G- flag if required.
|
---|
530 | * @return An empty string if get local copy is true.
|
---|
531 | */
|
---|
532 | protected String getGetLocalCopy() {
|
---|
533 | return (!getLocalCopy) ? FLAG_NO_GET : "";
|
---|
534 | }
|
---|
535 |
|
---|
536 | /**
|
---|
537 | * Gets the value of the fail on error flag.
|
---|
538 | * @return True if the FailOnError flag has been set or if 'writablefiles=skip'.
|
---|
539 | */
|
---|
540 | private boolean getFailOnError() {
|
---|
541 | return getWritableFiles().equals(WRITABLE_SKIP) ? false : failOnError;
|
---|
542 | }
|
---|
543 |
|
---|
544 |
|
---|
545 | /**
|
---|
546 | * Gets the value set for the FileTimeStamp.
|
---|
547 | * if it equals "current" then we return -GTC
|
---|
548 | * if it equals "modified" then we return -GTM
|
---|
549 | * if it equals "updated" then we return -GTU
|
---|
550 | * otherwise we return -GTC
|
---|
551 | *
|
---|
552 | * @return The default file time flag, if not set.
|
---|
553 | */
|
---|
554 | public String getFileTimeStamp() {
|
---|
555 | if (timestamp == null) {
|
---|
556 | return "";
|
---|
557 | } else if (timestamp.getValue().equals(TIME_MODIFIED)) {
|
---|
558 | return FLAG_FILETIME_MODIFIED;
|
---|
559 | } else if (timestamp.getValue().equals(TIME_UPDATED)) {
|
---|
560 | return FLAG_FILETIME_UPDATED;
|
---|
561 | } else {
|
---|
562 | return FLAG_FILETIME_DEF;
|
---|
563 | }
|
---|
564 | }
|
---|
565 |
|
---|
566 |
|
---|
567 | /**
|
---|
568 | * Gets the value to determine the behaviour when encountering writable files.
|
---|
569 | * @return An empty String, if not set.
|
---|
570 | */
|
---|
571 | public String getWritableFiles() {
|
---|
572 | if (writableFiles == null) {
|
---|
573 | return "";
|
---|
574 | } else if (writableFiles.getValue().equals(WRITABLE_REPLACE)) {
|
---|
575 | return FLAG_REPLACE_WRITABLE;
|
---|
576 | } else if (writableFiles.getValue().equals(WRITABLE_SKIP)) {
|
---|
577 | // ss.exe exits with '100', when files have been skipped
|
---|
578 | // so we have to ignore the failure
|
---|
579 | failOnError = false;
|
---|
580 | return FLAG_SKIP_WRITABLE;
|
---|
581 | } else {
|
---|
582 | return "";
|
---|
583 | }
|
---|
584 | }
|
---|
585 |
|
---|
586 | /**
|
---|
587 | * Sets up the required environment and executes the command line.
|
---|
588 | *
|
---|
589 | * @param cmd The command line to execute.
|
---|
590 | * @return The return code from the exec'd process.
|
---|
591 | */
|
---|
592 | private int run(Commandline cmd) {
|
---|
593 | try {
|
---|
594 | Execute exe = new Execute(new LogStreamHandler(this,
|
---|
595 | Project.MSG_INFO,
|
---|
596 | Project.MSG_WARN));
|
---|
597 |
|
---|
598 | // If location of ss.ini is specified we need to set the
|
---|
599 | // environment-variable SSDIR to this value
|
---|
600 | if (serverPath != null) {
|
---|
601 | String[] env = exe.getEnvironment();
|
---|
602 | if (env == null) {
|
---|
603 | env = new String[0];
|
---|
604 | }
|
---|
605 | String[] newEnv = new String[env.length + 1];
|
---|
606 | for (int i = 0; i < env.length; i++) {
|
---|
607 | newEnv[i] = env[i];
|
---|
608 | }
|
---|
609 | newEnv[env.length] = "SSDIR=" + serverPath;
|
---|
610 |
|
---|
611 | exe.setEnvironment(newEnv);
|
---|
612 | }
|
---|
613 |
|
---|
614 | exe.setAntRun(getProject());
|
---|
615 | exe.setWorkingDirectory(getProject().getBaseDir());
|
---|
616 | exe.setCommandline(cmd.getCommandline());
|
---|
617 | // Use the OS launcher so we get environment variables
|
---|
618 | exe.setVMLauncher(false);
|
---|
619 | return exe.execute();
|
---|
620 | } catch (IOException e) {
|
---|
621 | throw new BuildException(e, getLocation());
|
---|
622 | }
|
---|
623 | }
|
---|
624 |
|
---|
625 | /**
|
---|
626 | * Calculates the start date for version comparison.
|
---|
627 | * <p>
|
---|
628 | * Calculates the date numDay days earlier than startdate.
|
---|
629 | * @param startDate The start date.
|
---|
630 | * @param daysToAdd The number of days to add.
|
---|
631 | * @return The calculated date.
|
---|
632 | * @throws ParseException
|
---|
633 | */
|
---|
634 | private String calcDate(String startDate, int daysToAdd) throws ParseException {
|
---|
635 | Date currentDate = new Date();
|
---|
636 | Calendar calendar = new GregorianCalendar();
|
---|
637 | currentDate = dateFormat.parse(startDate);
|
---|
638 | calendar.setTime(currentDate);
|
---|
639 | calendar.add(Calendar.DATE, daysToAdd);
|
---|
640 | return dateFormat.format(calendar.getTime());
|
---|
641 | }
|
---|
642 |
|
---|
643 | /**
|
---|
644 | * Changes the password to '***' so it isn't displayed on screen if the build fails
|
---|
645 | *
|
---|
646 | * @param cmd The command line to clean
|
---|
647 | * @return The command line as a string with out the password
|
---|
648 | */
|
---|
649 | private String formatCommandLine(Commandline cmd) {
|
---|
650 | StringBuffer sBuff = new StringBuffer(cmd.toString());
|
---|
651 | int indexUser = sBuff.substring(0).indexOf(FLAG_LOGIN);
|
---|
652 | if (indexUser > 0) {
|
---|
653 | int indexPass = sBuff.substring(0).indexOf(",", indexUser);
|
---|
654 | int indexAfterPass = sBuff.substring(0).indexOf(" ", indexPass);
|
---|
655 |
|
---|
656 | for (int i = indexPass + 1; i < indexAfterPass; i++) {
|
---|
657 | sBuff.setCharAt(i, '*');
|
---|
658 | }
|
---|
659 | }
|
---|
660 | return sBuff.toString();
|
---|
661 | }
|
---|
662 |
|
---|
663 | /**
|
---|
664 | * Extention of EnumeratedAttribute to hold the values for file time stamp.
|
---|
665 | */
|
---|
666 | public static class CurrentModUpdated extends EnumeratedAttribute {
|
---|
667 | /**
|
---|
668 | * Gets the list of allowable values.
|
---|
669 | * @return The values.
|
---|
670 | */
|
---|
671 | public String[] getValues() {
|
---|
672 | return new String[] {TIME_CURRENT, TIME_MODIFIED, TIME_UPDATED};
|
---|
673 | }
|
---|
674 | }
|
---|
675 |
|
---|
676 | /**
|
---|
677 | * Extention of EnumeratedAttribute to hold the values for writable filess.
|
---|
678 | */
|
---|
679 | public static class WritableFiles extends EnumeratedAttribute {
|
---|
680 | /**
|
---|
681 | * Gets the list of allowable values.
|
---|
682 | * @return The values.
|
---|
683 | */
|
---|
684 | public String[] getValues() {
|
---|
685 | return new String[] {WRITABLE_REPLACE, WRITABLE_SKIP, WRITABLE_FAIL};
|
---|
686 | }
|
---|
687 | }
|
---|
688 | }
|
---|