1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest;
  28 
  29 import java.io.File;
  30 import java.io.FileNotFoundException;
  31 import java.io.IOException;
  32 import java.net.URL;
  33 import java.util.Vector;
  34 
  35 import com.sun.javatest.util.I18NResourceBundle;
  36 
  37 /**
  38  * A basic implementation of Parameters for all except the EnvParameters
  39  * subsection.
  40  */
  41 public abstract class BasicParameters
  42     implements
  43         Parameters,
  44         Parameters.MutableTestsParameters,
  45         Parameters.MutableExcludeListParameters,
  46         Parameters.MutableKeywordsParameters,
  47         Parameters.MutablePriorStatusParameters,
  48         Parameters.MutableConcurrencyParameters,
  49         Parameters.MutableTimeoutFactorParameters
  50 {
  51     //---------------------------------------------------------------------
  52 
  53     public TestSuite getTestSuite() {
  54         return testSuite;
  55     }
  56 
  57     /**
  58      * Set the test suite for the test run. The test suite may only be set once.
  59      * If the test suite cannot be opened, isValid will return false, and
  60      * getErrorMessage will contain an error message.
  61      * @param file a path defining the test suite to be opened and set as the test
  62      * suite for the test run.
  63      * @see #getTestSuite
  64      * @see #setTestSuite(TestSuite)
  65      */
  66     public void setTestSuite(File file) {
  67         if (file == null)
  68             testSuiteError = i18n.getString("bp.noTestSuite");
  69         else {
  70             try {
  71                 setTestSuite(TestSuite.open(file));
  72                 //System.err.println("BP.setTestSuite: " + file + " opened");
  73             }
  74             catch (FileNotFoundException e) {
  75                 testSuiteError = i18n.getString("bp.cantFindTestSuite", file);
  76             }
  77             catch (TestSuite.Fault e) {
  78                 testSuiteError = i18n.getString("bp.badTestSuite", e.getMessage());
  79             }
  80         }
  81     }
  82 
  83     /**
  84      * Set the test suite for the test run. The test suite may only be set once.
  85      * @param ts the test suite to be set.
  86      * @see #getTestSuite
  87      * @throws NullPointerException if ts is null
  88      * @throws IllegalStateException if the test suite has already been set to
  89      * something different
  90      */
  91     public void setTestSuite(TestSuite ts) {
  92         if (ts == null)
  93             throw new NullPointerException();
  94 
  95         if (testSuite != null && testSuite != ts)
  96             throw new IllegalStateException();
  97 
  98         testSuite = ts;
  99         testSuiteError = null;
 100     }
 101 
 102     private boolean isTestSuiteOK() {
 103         return (testSuiteError == null);
 104     }
 105 
 106 
 107     private TestSuite testSuite;
 108 
 109     /**
 110      * A string to identify any errors that may have occurred when
 111      * setting the test suite, or null if there were no such errors.
 112      */
 113     protected String testSuiteError;
 114 
 115     //---------------------------------------------------------------------
 116 
 117     public WorkDirectory getWorkDirectory() {
 118         return workDir;
 119     }
 120 
 121     /**
 122      * Set the work directory for the test run. The work directory may only
 123      * be set once.
 124      * If the work directory cannot be opened, isValid will return false, and
 125      * getErrorMessage will contain an error message.
 126      * The test suite must already be set before this method is called.
 127      * @param dir a path defining the work directory to be opened and set as the
 128      * work directory for the test run.
 129      * @see #getWorkDirectory
 130      * @see #setWorkDirectory(WorkDirectory)
 131      */
 132     public void setWorkDirectory(File dir) {
 133         if (dir == null)
 134             workDirError = i18n.getString("bp.workDirMissing");
 135         else if (isTestSuiteOK()) {
 136             try {
 137                 TestSuite ts = getTestSuite();
 138                 if (dir.exists()) {
 139                     if (WorkDirectory.isWorkDirectory(dir)) {
 140                         setWorkDirectory(WorkDirectory.open(dir, ts));
 141                         workDirError = null;
 142                     }
 143                     else if (WorkDirectory.isEmptyDirectory(dir)) {
 144                         workDir = WorkDirectory.create(dir, ts);
 145                         workDirError = null;
 146                     }
 147                     else
 148                         workDirError = i18n.getString("bp.badWorkDir", dir.getPath());
 149                 }
 150                 else
 151                     workDirError = i18n.getString("bp.cantFindWorkDir", dir.getPath());
 152             }
 153             catch (FileNotFoundException e) {
 154                 workDirError = i18n.getString("bp.cantFindWorkDir", dir.getPath());
 155             }
 156             catch (WorkDirectory.Fault e) {
 157                 workDirError = i18n.getString("bp.workDirError", e.getMessage());
 158             }
 159         }
 160         else
 161             workDirError = i18n.getString("bp.noTestSuite");
 162     }
 163 
 164     /**
 165      * Set the work directory for the test run.
 166      * The work directory may only be set once.
 167      * If the test suite has already been set, it must exactly match the test suite
 168      * for the work directory; if the test suite has not yet been set, it will
 169      * be set to the test suite for this work directory.
 170      * @param wd the work directory to be set.
 171      * @see #getWorkDirectory
 172      * @throws NullPointerException if wd is null
 173      * @throws IllegalStateException if the work directory has already been set to
 174      * something different
 175      */
 176     public void setWorkDirectory(WorkDirectory wd) {
 177         if (wd == null)
 178             throw new NullPointerException();
 179 
 180         if (workDir != null && workDir != wd)
 181             throw new IllegalStateException();
 182 
 183         if (testSuite != null && wd.getTestSuite() != testSuite)
 184             throw new IllegalArgumentException();
 185 
 186         if (testSuite == null)
 187             setTestSuite(wd.getTestSuite());
 188         workDir = wd;
 189     }
 190 
 191     private boolean isWorkDirectoryOK() {
 192         return (workDirError == null);
 193     }
 194 
 195     private WorkDirectory workDir;
 196 
 197     /**
 198      * A string to identify any errors that may have occurred when
 199      * setting the work directory, or null if there were no such errors.
 200      */
 201     protected String workDirError;
 202 
 203     //---------------------------------------------------------------------
 204 
 205     public Parameters.TestsParameters getTestsParameters() {
 206         return this;
 207     }
 208 
 209     public String[] getTests() {
 210         return tests;
 211     }
 212 
 213     public void setTests(String[] tests) {
 214         if (tests == null)
 215             testsMode = MutableTestsParameters.ALL_TESTS;
 216         else {
 217             testsMode = MutableTestsParameters.SPECIFIED_TESTS;
 218             this.tests = tests;
 219         }
 220     }
 221 
 222     public int getTestsMode() {
 223         return testsMode;
 224     }
 225 
 226     public void setTestsMode(int mode) {
 227         if (mode != ALL_TESTS &&
 228             mode != SPECIFIED_TESTS)
 229             throw new IllegalArgumentException();
 230 
 231         testsMode = mode;
 232     }
 233 
 234     public String[] getSpecifiedTests() {
 235         return tests;
 236     }
 237 
 238     public void setSpecifiedTests(String[] tests) {
 239         if (tests == null)
 240             throw new NullPointerException();
 241 
 242         this.tests = tests;
 243     }
 244 
 245     private boolean isTestsOK() {
 246         return true;
 247     }
 248 
 249     private int testsMode = MutableTestsParameters.ALL_TESTS;
 250     private String[] tests;
 251 
 252     //---------------------------------------------------------------------
 253 
 254     public Parameters.ExcludeListParameters getExcludeListParameters() {
 255         return this;
 256     }
 257 
 258     public File[] getExcludeFiles() {
 259         TestSuite ts = getTestSuite();
 260         switch (excludeMode) {
 261         case INITIAL_EXCLUDE_LIST:
 262             if (ts == null)
 263                 return null;
 264             File df = ts.getInitialExcludeList();
 265             if (df == null)
 266                 return null;
 267             return new File[] { df };
 268 
 269         case LATEST_EXCLUDE_LIST:
 270             if (ts == null)
 271                 return null;
 272             URL u = ts.getLatestExcludeList();
 273             if (u == null)
 274                 return null;
 275             WorkDirectory wd = getWorkDirectory();
 276             if (wd == null)
 277                 return null;
 278             return new File[] { wd.getSystemFile("latest.jtx") };
 279 
 280         case CUSTOM_EXCLUDE_LIST:
 281             return customExcludeFiles;
 282 
 283         default:
 284             return null;
 285         }
 286     }
 287 
 288     public void setExcludeFiles(File[] files) {
 289         if (files == null || files.length == 0)
 290             setExcludeMode(NO_EXCLUDE_LIST);
 291         else {
 292             setExcludeMode(CUSTOM_EXCLUDE_LIST);
 293             setCustomExcludeFiles(files);
 294         }
 295     }
 296 
 297     public ExcludeList getExcludeList() {
 298         updateExcludeList();
 299         return cachedExcludeList;
 300     }
 301 
 302     public TestFilter getExcludeListFilter() {
 303         updateExcludeList();
 304         return cachedExcludeListFilter;
 305     }
 306 
 307     public int getExcludeMode() {
 308         return excludeMode;
 309     }
 310 
 311     public void setExcludeMode(int mode) {
 312         excludeMode = mode;
 313     }
 314 
 315     public File[] getCustomExcludeFiles() {
 316         return customExcludeFiles;
 317     }
 318 
 319     public void setCustomExcludeFiles(File[] files) {
 320         customExcludeFiles = files;
 321     }
 322 
 323     public boolean isLatestExcludeAutoCheckEnabled() {
 324         return false;
 325     }
 326 
 327     public void setLatestExcludeAutoCheckEnabled(boolean b) {
 328         latestExcludeAutoCheck = b;
 329     }
 330 
 331     public int getLatestExcludeAutoCheckMode() {
 332         return latestExcludeAutoCheckMode;
 333     }
 334 
 335     public void setLatestExcludeAutoCheckMode(int mode) {
 336         latestExcludeAutoCheckMode = mode;
 337     }
 338 
 339     public int getLatestExcludeAutoCheckInterval() {
 340         return latestExcludeAutoCheckInterval;
 341     }
 342 
 343     public void setLatestExcludeAutoCheckInterval(int days) {
 344         latestExcludeAutoCheckInterval = days;;
 345     }
 346 
 347     private boolean isExcludeListOK() {
 348         return (excludeListError == null);
 349     }
 350 
 351     private File[] getAbsoluteExcludeFiles() {
 352         updateAbsoluteExcludeFiles();
 353         return cachedAbsExcludeFiles;
 354     }
 355     private void updateAbsoluteExcludeFiles() {
 356         TestSuite ts = getTestSuite();
 357         File base = (ts == null ? null : ts.getRootDir());
 358         File[] excludeFiles = getExcludeFiles();
 359         if (cachedAbsExcludeFiles == null ||
 360             cachedAbsExcludeFiles_base != base ||
 361             cachedAbsExcludeFiles_excludeFiles != excludeFiles) {
 362             cachedAbsExcludeFiles = getAbsoluteFiles(base, excludeFiles);
 363         }
 364     }
 365 
 366     private void updateExcludeList() {
 367         File[] absExclFiles = getAbsoluteExcludeFiles();
 368         if (cachedExcludeList == null
 369             || !equal(cachedExcludeList_absExclFiles, absExclFiles)) {
 370             try {
 371                 if (absExclFiles == null)
 372                     cachedExcludeList = new ExcludeList();
 373                 else
 374                     cachedExcludeList = new ExcludeList(cachedAbsExcludeFiles);
 375                 cachedExcludeList_absExclFiles = cachedAbsExcludeFiles;
 376                 cachedExcludeListFilter = new ExcludeListFilter(cachedExcludeList);
 377                 excludeListError = null;
 378             }
 379             catch (FileNotFoundException e) {
 380                 cachedExcludeList = null;
 381                 cachedExcludeListFilter = null;
 382                 excludeListError = i18n.getString("bp.exclListNotFound", e.getMessage());
 383             }
 384             catch (IOException e) {
 385                 cachedExcludeList = null;
 386                 cachedExcludeListFilter = null;
 387                 excludeListError = i18n.getString("bp.exclListFault", e);
 388             }
 389             catch (ExcludeList.Fault e) {
 390                 cachedExcludeList = null;
 391                 cachedExcludeListFilter = null;
 392                 excludeListError = i18n.getString("bp.exclListFault", e.getMessage());
 393             }
 394         }
 395     }
 396 
 397     private int excludeMode = NO_EXCLUDE_LIST;
 398     private boolean latestExcludeAutoCheck;
 399     private int latestExcludeAutoCheckMode;
 400     private int latestExcludeAutoCheckInterval;
 401     private File[] customExcludeFiles = { };
 402 
 403 
 404     private File[] cachedAbsExcludeFiles;
 405     private File cachedAbsExcludeFiles_base;
 406     private File[] cachedAbsExcludeFiles_excludeFiles;
 407     private ExcludeList cachedExcludeList;
 408     private File[] cachedExcludeList_absExclFiles;
 409     private ExcludeListFilter cachedExcludeListFilter;
 410     /**
 411      * A string to identify any errors that may have occurred when
 412      * setting the exclude list parameters, or null if there were no such errors.
 413      */
 414     protected String excludeListError;
 415 
 416     //---------------------------------------------------------------------
 417 
 418     public Parameters.KeywordsParameters getKeywordsParameters() {
 419         return this;
 420     }
 421 
 422     public Keywords getKeywords() {
 423         updateCachedKeywords();
 424         return cachedKeywords;
 425     }
 426 
 427     public void setKeywords(int mode, String value) {
 428         if (value == null)
 429             keywordsMode = NO_KEYWORDS;
 430         else {
 431             keywordsMode = MATCH_KEYWORDS;
 432             keywordsMatchMode = mode;
 433             keywordsMatchValue = value;
 434         }
 435     }
 436 
 437     public TestFilter getKeywordsFilter() {
 438         updateCachedKeywords();
 439         if (keywordsMode == NO_KEYWORDS)
 440             return null;
 441         else
 442             return cachedKeywordsFilter;
 443     }
 444 
 445     public int getKeywordsMode() {
 446         return keywordsMode;
 447     }
 448 
 449     public void setKeywordsMode(int mode) {
 450         keywordsMode = mode;
 451     }
 452 
 453     public int getMatchKeywordsMode() {
 454         return keywordsMatchMode;
 455     }
 456 
 457     public String getMatchKeywordsValue() {
 458         return keywordsMatchValue;
 459     }
 460 
 461     public void setMatchKeywords(int mode, String value) {
 462         keywordsMatchMode = mode;
 463         keywordsMatchValue = value;
 464     }
 465 
 466     private void updateCachedKeywords() {
 467         if (keywordsMode == NO_KEYWORDS) {
 468             cachedKeywordsMatchMode = -1;
 469             cachedKeywordsMatchValue = null;
 470             cachedKeywords = null;
 471             cachedKeywordsFilter = null;
 472             keywordsError = null;
 473         }
 474         else {
 475             if (cachedKeywordsMatchMode != keywordsMatchMode
 476                 || cachedKeywordsMatchValue == null
 477                 || !cachedKeywordsMatchValue.equals(keywordsMatchValue)) {
 478                 try {
 479                     cachedKeywordsMatchMode = keywordsMatchMode;
 480                     cachedKeywordsMatchValue = keywordsMatchValue;
 481                     String op = (keywordsMatchMode == EXPR ? "expr"
 482                                  : keywordsMatchMode == ALL_OF ? "all of"
 483                                  : "any of");
 484                     cachedKeywords = Keywords.create(op, keywordsMatchValue);
 485                     cachedKeywordsFilter = new KeywordsFilter(cachedKeywords);
 486                 }
 487                 catch (Keywords.Fault e) {
 488                     cachedKeywords = null;
 489                     cachedKeywordsFilter = null;
 490                     keywordsError = i18n.getString("bp.badKeywords", e.getMessage());
 491                 }
 492             }
 493         }
 494     }
 495 
 496     private boolean isKeywordsOK() {
 497         updateCachedKeywords();
 498         return (keywordsError == null);
 499     }
 500 
 501     private int keywordsMode = NO_KEYWORDS;
 502     private int keywordsMatchMode = EXPR;
 503     private String keywordsMatchValue;
 504 
 505     private int cachedKeywordsMatchMode;
 506     private String cachedKeywordsMatchValue;
 507     private Keywords cachedKeywords;
 508     private TestFilter cachedKeywordsFilter;
 509     /**
 510      * A string to identify any errors that may have occurred when
 511      * setting the keywords parameters, or null if there were no such errors.
 512      */
 513     protected String keywordsError;
 514 
 515     //---------------------------------------------------------------------
 516 
 517     public Parameters.PriorStatusParameters getPriorStatusParameters() {
 518         return this;
 519     }
 520 
 521     public boolean[] getPriorStatusValues() {
 522         if (priorStatusMode == NO_PRIOR_STATUS)
 523             return null;
 524         else
 525             return priorStatusValues;
 526     }
 527 
 528     public void setPriorStatusValues(boolean[] values) {
 529         if (values == null)
 530             priorStatusMode = NO_PRIOR_STATUS;
 531         else {
 532             priorStatusMode = MATCH_PRIOR_STATUS;
 533             priorStatusValues = values;
 534         }
 535     }
 536 
 537     public TestFilter getPriorStatusFilter() {
 538         WorkDirectory wd = getWorkDirectory();
 539         TestResultTable r = (wd == null ? null : wd.getTestResultTable());
 540         boolean[] s = getPriorStatusValues();
 541         if (r == null || s == null)
 542             cachedPriorStatusFilter = null;
 543         else if (cachedPriorStatusFilter == null
 544                  || cachedPriorStatusFilter.getTestResultTable() != r
 545                  || !equal(cachedPriorStatusFilter.getStatusValues(), s)) {
 546             cachedPriorStatusFilter = new StatusFilter(s, r);
 547         }
 548 
 549         return cachedPriorStatusFilter;
 550     }
 551 
 552     public int getPriorStatusMode() {
 553         return priorStatusMode;
 554     }
 555 
 556     public void setPriorStatusMode(int mode) {
 557         if (mode != NO_PRIOR_STATUS &&
 558             mode != MATCH_PRIOR_STATUS)
 559             throw new IllegalArgumentException();
 560 
 561         priorStatusMode = mode;
 562     }
 563 
 564     public boolean[] getMatchPriorStatusValues() {
 565         return priorStatusValues;
 566     }
 567 
 568     public void setMatchPriorStatusValues(boolean[] v) {
 569         if (v == null)
 570             throw new NullPointerException();
 571 
 572         if (v.length != Status.NUM_STATES)
 573             throw new IllegalArgumentException();
 574 
 575         priorStatusValues = v;
 576     }
 577 
 578     private boolean isPriorStatusOK() {
 579         return true;
 580     }
 581 
 582     private int priorStatusMode = NO_PRIOR_STATUS;
 583     private boolean[] priorStatusValues = new boolean[Status.NUM_STATES];
 584     private StatusFilter cachedPriorStatusFilter;
 585 
 586     //---------------------------------------------------------------------
 587 
 588     public Parameters.ConcurrencyParameters getConcurrencyParameters() {
 589         return this;
 590     }
 591 
 592     public int getConcurrency() {
 593         return concurrency;
 594     }
 595 
 596     public void setConcurrency(int conc) {
 597         if (conc <= 0) {
 598             concurrencyError =
 599                 i18n.getString("bp.badConcurrency", new Integer(conc));
 600             concurrency = 1;
 601         }
 602         else {
 603             concurrencyError = null;
 604             concurrency = conc;
 605         }
 606     }
 607 
 608     private boolean isConcurrencyOK() {
 609         return (concurrencyError == null);
 610     }
 611 
 612     private int concurrency = 1;
 613     /**
 614      * A string to identify any errors that may have occurred when
 615      * setting the concurrency, or null if there were no such errors.
 616      */
 617     protected String concurrencyError;
 618 
 619     //---------------------------------------------------------------------
 620 
 621     public Parameters.TimeoutFactorParameters getTimeoutFactorParameters() {
 622         return this;
 623     }
 624 
 625     public float getTimeoutFactor() {
 626         return timeoutFactor;
 627     }
 628 
 629     public void setTimeoutFactor(float tf) {
 630         if (tf <= 0) {
 631             timeoutFactorError = i18n.getString("bp.badTimeout", new Float(tf));
 632             timeoutFactor = 1;
 633         }
 634         else {
 635             timeoutFactorError = null;
 636             timeoutFactor = tf;
 637         }
 638     }
 639 
 640     private boolean isTimeoutFactorOK() {
 641         return (timeoutFactorError == null);
 642     }
 643 
 644     private float timeoutFactor = 1;
 645     /**
 646      * A string to identify any errors that may have occurred when
 647      * setting the timeout factor, or null if there were no such errors.
 648      */
 649     protected String timeoutFactorError;
 650 
 651     //---------------------------------------------------------------------
 652 
 653     public TestFilter getRelevantTestFilter() {
 654         TestSuite ts = getTestSuite();
 655         TestEnvironment env = getEnv();
 656         if (ts == null || env == null)
 657             cachedRelevantTestFilter = null;
 658         else if (cachedRelevantTestFilter == null ||
 659                  ts != cachedRelevantTestFilterTestSuite ||
 660                  env != cachedRelevantTestFilterEnv) {
 661             cachedRelevantTestFilter = ts.createTestFilter(env);
 662         }
 663         return cachedRelevantTestFilter;
 664     }
 665 
 666     private TestFilter cachedRelevantTestFilter;
 667     private TestSuite cachedRelevantTestFilterTestSuite; // do we need this?
 668     private TestEnvironment cachedRelevantTestFilterEnv;
 669 
 670     public synchronized TestFilter[] getFilters() {
 671         Vector<TestFilter> v = new Vector<>();
 672 
 673         TestFilter excludeFilter = getExcludeListFilter();
 674         if (excludeFilter != null)
 675             v.addElement(excludeFilter);
 676 
 677         TestFilter keywordFilter = getKeywordsFilter();
 678         if (keywordFilter != null)
 679             v.addElement(keywordFilter);
 680 
 681         TestFilter statusFilter = getPriorStatusFilter();
 682         if (statusFilter != null)
 683             v.addElement(statusFilter);
 684 
 685         TestFilter testSuiteFilter = getRelevantTestFilter();
 686         if (testSuiteFilter != null)
 687         v.addElement(testSuiteFilter);
 688 
 689         if (v.size() == 0)
 690             return null;
 691         else if (equal(v, cachedTestFilters))
 692             return cachedTestFilters;
 693         else {
 694             TestFilter[] filters = new TestFilter[v.size()];
 695             v.copyInto(filters);
 696             return filters;
 697         }
 698 
 699     }
 700 
 701     private TestFilter[] cachedTestFilters;
 702 
 703     //---------------------------------------------------------------------
 704 
 705     public boolean isValid() {
 706         return (   isTestSuiteOK()
 707                 && isWorkDirectoryOK()
 708                 && isTestsOK()
 709                 && isExcludeListOK()
 710                 && isKeywordsOK()
 711                 && isPriorStatusOK()
 712                 && isConcurrencyOK()
 713                 && isTimeoutFactorOK());
 714     }
 715 
 716     public String getErrorMessage() {
 717         return (  testSuiteError != null ? testSuiteError
 718                 : workDirError != null ? workDirError
 719                 : excludeListError != null ? excludeListError
 720                 : keywordsError != null ? keywordsError
 721                 : concurrencyError != null ? concurrencyError
 722                 : timeoutFactorError != null ? timeoutFactorError
 723                 : null);
 724     }
 725 
 726     //---------------------------------------------------------------------
 727 
 728     /**
 729      * Convert a set of files to be absolute files. Files that are already
 730      * absolute are left unchanged; relative files are evaluated relative to
 731      * a specified base directory.
 732      * @param baseDir The base directory for any relative files
 733      * @param files The files to be made absolute, or null if none
 734      * @return the given files with any relative files having been evaluated
 735      * relative to the given base directory, or null if files was null.
 736      */
 737     protected static File[] getAbsoluteFiles(File baseDir, File[] files) {
 738         if (files == null)
 739             return null;
 740 
 741         boolean allAbsolute = true;
 742         for (int i = 0; i < files.length && allAbsolute; i++)
 743             allAbsolute = files[i].isAbsolute();
 744 
 745         if (allAbsolute)
 746             return files;
 747 
 748         File[] absoluteFiles = new File[files.length];
 749         for (int i = 0; i < files.length; i++) {
 750             File f = files[i];
 751             absoluteFiles[i] = (f.isAbsolute() ? f : new File(baseDir, f.getPath()));
 752         }
 753 
 754         return absoluteFiles;
 755     }
 756 
 757     //---------------------------------------------------------------------
 758 
 759     /**
 760      * Compare two boolean arrays for equality.
 761      * @param b1 the first array to be compared
 762      * @param b2 the second array to be compared
 763      * @return true and only if both arguments are null, or if both are not null
 764      * and are element-wise equal.
 765      */
 766     protected static boolean equal(boolean[] b1, boolean[] b2) {
 767         if (b1 == null || b2 == null)
 768             return (b1 == b2);
 769 
 770         if (b1.length != b2.length)
 771             return false;
 772 
 773         for (int i = 0; i < b1.length; i++) {
 774             if (b1[i] != b2[i])
 775                 return false;
 776         }
 777 
 778         return true;
 779     }
 780 
 781     /**
 782      * Compare two arrays of Files for equality.
 783      * @param f1 the first array to be compared
 784      * @param f2 the second array to be compared
 785      * @return true and only if both arguments are null, or if both are not null
 786      * and are element-wise equal.
 787      */
 788     protected static boolean equal(File[] f1, File[] f2) {
 789         if (f1 == null || f2 == null)
 790             return (f1 == f2);
 791 
 792         if (f1.length != f2.length)
 793             return false;
 794 
 795         for (int i = 0; i < f1.length; i++) {
 796             if (f1[i] != f2[i])
 797                 return false;
 798         }
 799 
 800         return true;
 801     }
 802 
 803     private static boolean equal(Vector v, TestFilter[] f) {
 804         if (f == null || v.size() != f.length)
 805             return false;
 806         for (int i = 0; i < v.size(); i++) {
 807             if (!v.elementAt(i).equals(f[i]))
 808                 return false;
 809         }
 810         return true;
 811     }
 812 
 813     //---------------------------------------------------------------------
 814 
 815     private static final I18NResourceBundle i18n =
 816         I18NResourceBundle.getBundleForClass(BasicParameters.class);
 817 }