1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2001, 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.interview;
  28 
  29 import java.io.File;
  30 import java.util.Arrays;
  31 import java.util.Iterator;
  32 import com.sun.interview.ErrorQuestion;
  33 import com.sun.interview.ExtensionFileFilter;
  34 import com.sun.interview.FileListQuestion;
  35 import com.sun.interview.FinalQuestion;
  36 import com.sun.interview.Interview;
  37 import com.sun.interview.Question;
  38 import com.sun.interview.StringQuestion;
  39 import com.sun.javatest.InterviewParameters;
  40 import com.sun.javatest.Parameters;
  41 import com.sun.javatest.TestEnvContext;
  42 import com.sun.javatest.TestEnvironment;
  43 import com.sun.javatest.TestSuite;
  44 
  45 
  46 /**
  47  * This interview collects the environment parameter, by means of environment (jte) files
  48  * and an environment name. It is normally used as one of a series of sub-interviews
  49  * that collect the parameter information for a test run. It is suitable for use with
  50  * legacy test suites that still rely on environments being provided with .jte files;
  51  * more sophisticated interviews should create a custom interview that collects the
  52  * environment data directly.
  53  */
  54 public class EnvironmentInterview
  55     extends Interview
  56     implements Parameters.LegacyEnvParameters
  57 {
  58     /**
  59      * Create an interview.
  60      * @param parent The parent interview of which this is a child.
  61      * @throws Interview.Fault if there is a problem while creating the interview.
  62      */
  63     public EnvironmentInterview(InterviewParameters parent)
  64         throws Interview.Fault
  65     {
  66         super(parent, "environment");
  67         this.parent = parent;
  68         setResourceBundle("i18n");
  69         setHelpSet("/com/sun/javatest/moreInfo/moreInfo.hs");
  70         setFirstQuestion(qEnvFiles);
  71     }
  72 
  73     /**
  74      * Get the environment files specified in the interview.
  75      * @return the list of files specified in the interview
  76      * @see #setEnvFiles
  77      */
  78     public File[] getEnvFiles() {
  79         return qEnvFiles.getValue();
  80     }
  81 
  82     public File[] getAbsoluteEnvFiles() {
  83         TestSuite ts = parent.getTestSuite();
  84         File tsRootDir = (ts == null ? null : ts.getRootDir());
  85         return getAbsoluteFiles(tsRootDir, getEnvFiles());
  86     }
  87 
  88     /**
  89      * Set the environment files for the interview.
  90      * @param files the environment files for the interview
  91      * @see #getEnvFiles
  92      */
  93     public void setEnvFiles(File[] files) {
  94         qEnvFiles.setValue(files);
  95     }
  96 
  97     /**
  98      * Get the environment name specified in the interview.
  99      * @return the environment name specified in the interview
 100      * @see #setEnvName
 101      */
 102     public String getEnvName() {
 103         return qEnv.getValue();
 104     }
 105 
 106     /**
 107      * Set the environment name for the interview.
 108      * @param name the environment name for the interview
 109      * @see #getEnvName
 110      */
 111     public void setEnvName(String name) {
 112         qEnv.setValue(name);
 113     }
 114 
 115     /**
 116      * Get the environment specified by the environment files and environment name,
 117      * or null, if it cannot be determined.
 118      * @return the environment determined by the interview, or null if it cannot be determined.
 119      * @see #getEnvFiles
 120      * @see #getEnvName
 121      */
 122     public TestEnvironment getEnv() {
 123         updateCachedEnv();
 124         return cachedEnv;
 125     }
 126 
 127 
 128     //----------------------------------------------------------------------------
 129     //
 130     // Env files
 131 
 132     private FileListQuestion qEnvFiles = new FileListQuestion(this, "envFiles") {
 133         {
 134             // I18N...
 135             setFilter(new ExtensionFileFilter(".jte", "Environment File"));
 136             setDuplicatesAllowed(false);
 137         }
 138 
 139         public File getBaseDirectory() {
 140             TestSuite ts = parent.getTestSuite();
 141             if (ts == null)
 142                 return null;
 143             else {
 144                 File r = ts.getRoot();
 145                 return r.isDirectory() ? r : r.getParentFile();
 146             }
 147         }
 148 
 149         protected Question getNext() {
 150             updateCachedEnvTable();
 151             if (cachedEnvTableError != null)
 152                 return qEnvTableError;
 153             else if (cachedEnvTable == null || cachedEnvTable.getEnvNames().length == 0)
 154                 return qNoEnvs;
 155             else
 156                 return qEnv;
 157         }
 158     };
 159 
 160     private TestEnvContext getEnvTable() {
 161         updateCachedEnvTable();
 162         return cachedEnvTable;
 163     }
 164 
 165     private void updateCachedEnvTable() {
 166         File[] absFiles = getAbsoluteEnvFiles();
 167         if (!equal(cachedEnvTable_absFiles, absFiles)) {
 168             try {
 169                 cachedEnvTable = new TestEnvContext(absFiles);
 170                 cachedEnvTableError = null;
 171             }
 172             catch (TestEnvContext.Fault e) {
 173                 cachedEnvTable = null;
 174                 cachedEnvTableError = e.getMessage();
 175             }
 176             cachedEnvTable_absFiles = absFiles;
 177         }
 178     }
 179 
 180     private TestEnvContext cachedEnvTable;
 181     private File[] cachedEnvTable_absFiles;
 182     private String cachedEnvTableError;
 183 
 184 
 185     //----------------------------------------------------------------------------
 186     //
 187     // No Env
 188 
 189     private ErrorQuestion qNoEnvs = new ErrorQuestion(this, "noEnvs");
 190 
 191 
 192     //----------------------------------------------------------------------------
 193     //
 194     // Env Table Error
 195 
 196     private ErrorQuestion qEnvTableError = new ErrorQuestion(this, "envTableError") {
 197         protected Object[] getTextArgs() {
 198             return new Object[] { cachedEnvTableError };
 199         }
 200     };
 201 
 202 
 203     //----------------------------------------------------------------------------
 204     //
 205     // Env
 206 
 207     private StringQuestion qEnv = new StringQuestion(this, "env") {
 208         public String[] getSuggestions() {
 209             // ensure the choices are up to date with envTable;
 210             // note that setting choices may smash the current value
 211             // if it's not a valid choice in the new set
 212             TestEnvContext envTable = getEnvTable();
 213             if (envTable != cachedEnvTable) {
 214                 String[] envNames;
 215                 if (envTable == null)
 216                     envNames = new String[0];
 217                 else {
 218                     String[] names = envTable.getEnvMenuNames();
 219                     Arrays.sort(names);
 220                     envNames = names;
 221                 }
 222                 setSuggestions(envNames);
 223                 cachedEnvTable = envTable;
 224             }
 225             return super.getSuggestions();
 226         }
 227 
 228         protected Question getNext() {
 229             if (value == null)
 230                 return null;
 231             else {
 232                 updateCachedEnv();
 233                 if (cachedEnv == null)
 234                     return cachedEnvError;
 235                 else
 236                     return qEnd;
 237             }
 238         }
 239 
 240         private TestEnvContext cachedEnvTable;
 241     };
 242 
 243     private void updateCachedEnv() {
 244         TestEnvContext envTable = getEnvTable();
 245         String envName = getEnvName();
 246         if (cachedEnv_envTable != envTable || !equal(cachedEnv_envName, envName)) {
 247             try {
 248                 if (envTable == null || envName == null || envName.length() == 0) {
 249                     cachedEnv = null;
 250                     cachedEnvError = null;
 251                 }
 252                 else {
 253                     cachedEnv = envTable.getEnv(envName);
 254                     if (cachedEnv == null) {
 255                         cachedEnvError = qEnvNotFound;
 256                         cachedEnvErrorArgs = new Object[] { envName };
 257                     }
 258                     else {
 259                         // verify all entries defined
 260                         cachedEnvError = null;
 261                         cachedEnvErrorArgs = null;
 262                         for (Iterator<TestEnvironment.Element> i = cachedEnv.elements().iterator();
 263                              i.hasNext() && cachedEnvError == null; ) {
 264                             TestEnvironment.Element entry = (i.next());
 265                             if (entry.getValue().indexOf("VALUE_NOT_DEFINED") >= 0) {
 266                                 cachedEnv = null;
 267                                 String eText =
 268                                     ( (entry.getDefinedInEnv() == null ? "" : "env." +  entry.getDefinedInEnv() + ".") +
 269                                       entry.getKey() + "=" + entry.getValue());
 270                                 cachedEnvError = qEnvUndefinedEntry;
 271                                 cachedEnvErrorArgs = new Object[] {eText, entry.getDefinedInFile()};
 272                             }
 273                         }
 274                     }
 275                 }
 276 
 277             }
 278             catch (TestEnvironment.Fault e) {
 279                 cachedEnv = null;
 280                 cachedEnvError = qEnvError;
 281                 cachedEnvErrorArgs = new Object[] { e.getMessage() };
 282             }
 283             cachedEnv_envTable = envTable;
 284             cachedEnv_envName = envName;
 285         }
 286     }
 287 
 288     private TestEnvironment cachedEnv;
 289     private TestEnvContext cachedEnv_envTable;
 290     private String cachedEnv_envName;
 291     private Question cachedEnvError;
 292     private Object[] cachedEnvErrorArgs;
 293 
 294 
 295 
 296     //----------------------------------------------------------------------------
 297     //
 298     // Env Error
 299 
 300     private ErrorQuestion qEnvError = new ErrorQuestion(this, "envError") {
 301         protected Object[] getTextArgs() {
 302             return cachedEnvErrorArgs;
 303         }
 304     };
 305 
 306     //----------------------------------------------------------------------------
 307     //
 308     // Env Not Found
 309 
 310     private ErrorQuestion qEnvNotFound = new ErrorQuestion(this, "envNotFound") {
 311         protected Object[] getTextArgs() {
 312             return cachedEnvErrorArgs;
 313         }
 314     };
 315 
 316     //----------------------------------------------------------------------------
 317     //
 318     // Env Undefined Entry
 319 
 320     private ErrorQuestion qEnvUndefinedEntry = new ErrorQuestion(this, "envUndefinedEntry") {
 321         protected Object[] getTextArgs() {
 322             return cachedEnvErrorArgs;
 323         }
 324     };
 325 
 326     //----------------------------------------------------------------------------
 327     //
 328     // End
 329 
 330     private Question qEnd = new FinalQuestion(this);
 331 
 332     //---------------------------------------------------------------------
 333 
 334     private static File[] getAbsoluteFiles(File baseDir, File[] files) {
 335         if (files == null)
 336             return null;
 337 
 338         if (baseDir == null)
 339             return files;
 340 
 341         boolean allAbsolute = true;
 342         for (int i = 0; i < files.length && allAbsolute; i++)
 343             allAbsolute = files[i].isAbsolute();
 344 
 345         if (allAbsolute)
 346             return files;
 347 
 348         File[] absoluteFiles = new File[files.length];
 349         for (int i = 0; i < files.length; i++) {
 350             File f = files[i];
 351             absoluteFiles[i] = (f.isAbsolute() ? f : new File(baseDir, f.getPath()));
 352         }
 353 
 354         return absoluteFiles;
 355     }
 356 
 357     //----------------------------------------------------------------------------
 358 
 359     private static boolean equal(File f1, File f2) {
 360         return (f1 == null ? f2 == null : f1.equals(f2));
 361     }
 362 
 363     private static boolean equal(File[] f1, File[] f2) {
 364         if (f1 == null || f2 == null)
 365             return (f1 == f2);
 366 
 367         if (f1.length != f2.length)
 368             return false;
 369 
 370         for (int i = 0; i < f1.length; i++) {
 371             if (!equal(f1[i], f2[i]))
 372                 return false;
 373         }
 374 
 375         return true;
 376     }
 377 
 378     private static boolean equal(String s1, String s2) {
 379         return (s1 == null ? s2 == null : s1.equals(s2));
 380     }
 381 
 382 
 383     //--------------------------------------------------------
 384 
 385     private InterviewParameters parent;
 386 }