1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2010, 2011 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 
  28 package com.sun.javatest.exec.template;
  29 
  30 import com.sun.javatest.InterviewParameters;
  31 import com.sun.javatest.TemplateUtilities;
  32 import com.sun.javatest.TestSuite;
  33 import com.sun.javatest.WorkDirectory;
  34 import com.sun.javatest.exec.BasicSession;
  35 import com.sun.javatest.exec.InterviewEditor;
  36 import com.sun.javatest.tool.FileHistory;
  37 import com.sun.javatest.util.I18NResourceBundle;
  38 import java.io.File;
  39 import java.util.Map;
  40 
  41 /**
  42  * Extension of the BasicConfig with template specific features.
  43  */
  44 public class TemplateSession extends BasicSession {
  45 
  46     /**
  47      * Instance of the template
  48      */
  49     protected final InterviewParameters templ;
  50 
  51     static final String TEMPLATE_PROP_NAME = "Template";
  52 
  53     private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(TemplateSession.class);
  54 
  55     /**
  56      * Creates a TemplateSession instance for the passed testSuite object.
  57      * Initializes template instance.
  58      * @param ts
  59      * @throws com.sun.javatest.exec.Config.Fault
  60      */
  61     public TemplateSession(TestSuite ts) throws Fault {
  62         super(ts);
  63         try {
  64             templ = ts.createInterview();
  65             templ.setTemplate(true);
  66         } catch (TestSuite.Fault f) {
  67             throw new Fault(f);
  68         }
  69     }
  70 
  71     /**
  72      * Extends parent's property list with the template name property.
  73      */
  74     @Override
  75     protected void initPropertyList() {
  76         super.initPropertyList();
  77         props.add(TEMPLATE_PROP_NAME);
  78     }
  79 
  80     @Override
  81     public String getValue(String name) {
  82         if (TEMPLATE_PROP_NAME.equals(name)) {
  83             if (templ == null) {
  84                 return null;
  85             }
  86             File f = templ.getFile();
  87             return f == null ?  null : f.getPath();
  88         } else {
  89             return super.getValue(name);
  90         }
  91     }
  92 
  93 
  94     @Override
  95     public void dispose() {
  96         templ.dispose();
  97         super.dispose();
  98     }
  99 
 100     @Override
 101     public void save(Map map) {
 102         if (templ.getFile() != null) {
 103             map.put("template", templ.getFile().getPath());
 104         }
 105         super.save(map);
 106     }
 107 
 108 
 109     @Override
 110     public void restore(Map map) throws Fault {
 111         super.restore(map);
 112         restoreTemplate(map);
 113     }
 114 
 115     protected void restoreTemplate(Map map) {
 116         String templPath = (String) map.get("template");
 117         if (templPath != null) {
 118             try {
 119                 if (!new File(templPath).exists() && getWorkDirectory() != null) {
 120                     // attempt to find relocated template
 121                     String oldWDpath = getWorkDirectory().getPrevWDPath();
 122                     String[] begins = WorkDirectory.getDiffInPaths(templPath, oldWDpath);
 123                     if (begins != null && templPath.startsWith(begins[1])) {
 124                         templPath = begins[0] + templPath.substring(begins[1].length());
 125                     }
 126                 }
 127                 templ.load(new File(templPath));
 128                 if (getWorkDirectory() != null) {
 129                     FileHistory.getFileHistory(getWorkDirectory(), TemplateEditor.TEMPLATE_HISTORY).add(templ.getFile());
 130                 }
 131                 templ.setTemplate(true);
 132                 notifyObservers(new E_NewTemplate(templ));
 133             } catch (Exception ex) {
 134                 System.err.println(i18n.getString("tcc.cantRestoreTemplate.err", templPath));
 135             }
 136         }
 137     }
 138 
 139 
 140     @Override
 141     public void update(Update u) throws Fault {
 142         if (u instanceof U_NewTemplate) {
 143             updateTemplate(((U_NewTemplate)u).templ);
 144         } else {
 145             super.update(u);
 146         }
 147     }
 148 
 149     @Override
 150     protected void updateNewConfig(InterviewParameters ip) throws Fault {
 151 
 152         String oldPath = templ.getTemplatePath();
 153         String newPath = ip.getTemplatePath();
 154         if (oldPath != newPath && oldPath != null && !oldPath.equals(newPath)) {
 155             try {
 156                 File templateFile = new File(newPath);
 157                 templ.load(templateFile);
 158                 templ.setFile(templateFile);
 159                 TemplateUtilities.setTemplateFile(getWorkDirectory(), templateFile, true);
 160                 notifyObservers(new E_NewTemplate(templ));
 161                 super.updateNewConfig(ip);
 162             } catch (Exception ex) {
 163                 throw new Fault(ex);
 164             }
 165         }
 166         else {
 167             super.updateNewConfig(ip);
 168         }
 169     }
 170 
 171 
 172     @Override
 173     protected void applyWorkDir(WorkDirectory wd) {
 174         super.applyWorkDir(wd);
 175         if (templ != null) {
 176             templ.setWorkDirectory(wd);
 177         }
 178     }
 179 
 180     /**
 181      * Loads template for the newly set workdir, notifies observers
 182      * with U_NewTemplate.
 183      * @param wd - work dir that just set
 184      * @throws com.sun.javatest.exec.Config.Fault
 185      */
 186     protected void loadTemplateFromWD(WorkDirectory wd) throws Fault {
 187         File templateFile = TemplateUtilities.getTemplateFile(wd);
 188         if (templateFile != null) {
 189             try {
 190                 //wd.getTestSuite().loadInterviewFromTemplate(templateFile,
 191                 //        templ);
 192                 InterviewParameters newValue = InterviewParameters.open(templateFile, wd);
 193                 InterviewEditor.copy(newValue, templ);
 194                 templ.setFile(templateFile);
 195                 TemplateUtilities.setTemplateFile(wd, templateFile, true);
 196                 notifyObservers(new E_NewTemplate(templ));
 197             } catch (Exception ex) {
 198                 throw new Fault(ex);
 199             }
 200         }
 201     }
 202 
 203     /**
 204      * @deprecated use getInterviewParameters()
 205      * @return getInterviewParameters()
 206      */
 207     @Deprecated
 208     public InterviewParameters getConfig() {
 209         return getInterviewParameters();
 210     }
 211 
 212     /**
 213      * Provides an access to the templ. We had to add this method to
 214      * preserve previous functionality...
 215      * @return
 216      */
 217     public InterviewParameters getTemplate() {
 218         return templ;
 219     }
 220 
 221     /**
 222      * Method invoked as a reaction on U_NewTemplate.
 223      * Checks if there are any changes in the update, if none - does nothing,
 224      * Otherwise, copies new values into the main template instance, notifies
 225      * observers with E_NewTemplate event.
 226      *
 227      * @param t - object with new template values.
 228      * @throws com.sun.javatest.exec.Config.Fault
 229      */
 230     protected void updateTemplate(InterviewParameters t) throws Fault {
 231         if (InterviewEditor.equal(t, templ) &&
 232                 t.getFile() != null && t.getFile().equals(templ.getFile())) {
 233             return; // nothing to update
 234         }
 235         try {
 236             InterviewEditor.copy(t, templ);
 237             TemplateUtilities.setTemplateFile(getWorkDirectory(), templ.getFile(), true);
 238         } catch (Exception e) {
 239             throw new Fault(e);
 240         }
 241         if (!templ.getTemplatePath().equals(getInterviewParameters().getTemplatePath())) {
 242             getInterviewParameters().clear();
 243             notifyObservers(new E_NewConfig(getInterviewParameters()));
 244         }
 245         notifyObservers(new E_NewTemplate(this.templ));
 246     }
 247 
 248     /**
 249      * Event signaling of a change happened to the template.
 250      */
 251     public static class E_NewTemplate implements Event {
 252         /**
 253          * InterviewParameters object filled with new values.
 254          */
 255         public final InterviewParameters templ;
 256         public E_NewTemplate(InterviewParameters templ) {
 257             this.templ = templ;
 258         }
 259     }
 260 
 261     /**
 262      * Update object to be applied when template changed.
 263      */
 264     public static class U_NewTemplate implements Update {
 265         /**
 266          * InterviewParameters object filled with new values.
 267          */
 268         public final InterviewParameters templ;
 269         public U_NewTemplate(InterviewParameters templ) {
 270             this.templ = templ;
 271         }
 272     }
 273 }