1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 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 package com.sun.javatest.exec;
  28 
  29 import java.util.Map;
  30 
  31 import javax.swing.JComponent;
  32 
  33 import com.sun.javatest.ObservableTestFilter;
  34 import com.sun.javatest.util.I18NResourceBundle;
  35 
  36 /**
  37  * This class adds the capability to have a filter which is
  38  * reconfigurable through the use of a GUI panel.  By definition, there
  39  * can be multiple instances of each <tt>ConfigurableTestFilter</tt> in
  40  * in the system at any one time.
  41  *
  42  * <p>
  43  * It is highly recommended that the GUI panel used to configure
  44  * this filter be a single panel, and not a complex tabbed or otherwise
  45  * "switchable" panel.
  46  *
  47  * <p>
  48  * Subclasses of this class should implement the abstract methods here and
  49  * those in ObservableTestFilter.
  50  *
  51  * @see com.sun.javatest.ObservableTestFilter
  52  */
  53 abstract class ConfigurableTestFilter extends ObservableTestFilter {
  54     /**
  55      * Nameless filters are not allowed.
  56      */
  57     private ConfigurableTestFilter() {
  58     }
  59 
  60     /**
  61      * Utility constructor for subclasses.
  62      * @param name The name to give this filter instance.  Must never be null.
  63      * @param e The ExecTool that owns this instance of the filter.  Should never be null.
  64      * @throws IllegalArgumentException If the either parameter is null.
  65      */
  66     protected ConfigurableTestFilter(String name, ExecModel e) {
  67         if (name == null)
  68             throw new IllegalArgumentException(i18n.getString("ctf.nullName"));
  69         if (e == null)
  70             throw new IllegalArgumentException(i18n.getString("ctf.nullExec"));
  71 
  72         instanceName = name;
  73         execModel = e;
  74     }
  75 
  76     /**
  77      * Utility constructor for subclasses.
  78      * @param map The map containing previous filter settings.
  79      * @param e The ExecTool that owns this instance of the filter.
  80      * @throws IllegalStateException If the instance name is not present in the map or
  81      *         the exec model argument is null.
  82      */
  83     protected ConfigurableTestFilter(Map<String, String> map, ExecModel e) {
  84         if (e == null)
  85             throw new IllegalArgumentException(i18n.getString("ctf.nullExec"));
  86 
  87         execModel = e;
  88         load(map);
  89 
  90     }
  91 
  92     /**
  93      * Create a new instance of this filter with the same associated exec model.
  94      * A default instance name will be supplied.
  95      */
  96     abstract ConfigurableTestFilter cloneInstance();
  97 
  98     /**
  99      * Overridden to create a new instance.
 100      * Settings from the original instance may not necessarily be copied.
 101      */
 102     public Object clone() {
 103         return cloneInstance();
 104     }
 105 
 106     /**
 107      * Get the basic (static) name for this filter.
 108      * This is different than <tt>getName()</tt> which returns a
 109      * customizable name.
 110      * @return The basic name for this filter.  Will never be null.
 111      */
 112     abstract String getBaseName();
 113 
 114     /**
 115      * Set the instance name.  This value should never be null.
 116      * Short meaningful names are recommended.
 117      *
 118      * @param text The name.
 119      * @throws IllegalArgumentException If the name parameter is null.
 120      * @see #getName()
 121      */
 122     void setInstanceName(String text) {
 123         if (text != null)
 124             instanceName = text;
 125         else
 126             throw new IllegalArgumentException(i18n.getString("ctf.nullName"));
 127     }
 128 
 129     /**
 130      * Load the state of this filter from a map.
 131      * This default implementation just loads the instance name.
 132      * @param map The map of strings to load from.
 133      * @return True if loading was successful and the filter is usable,
 134      *         false if the operation failed.
 135      * @throws IllegalStateException If the instance name is not present in the map.
 136      */
 137     boolean load(Map<String, String> map) {
 138         instanceName = map.get(INSTANCE_KEY);
 139 
 140         if (instanceName == null)
 141             throw new IllegalStateException(i18n.getString("ctf.mapNoName"));
 142 
 143         return true;
 144     }
 145 
 146     /**
 147      * Save the state of this filter to a map.
 148      * This default implementation just saves the instance name.  You may use
 149      * any key strings except those starting with the string "meta".
 150      * @param map The map to save to.
 151      * @return True if saving was successful, false if the operation failed.
 152      */
 153     boolean save(Map<String, String> map) {
 154         map.put(INSTANCE_KEY, instanceName);
 155 
 156         return true;
 157     }
 158 
 159     /**
 160      * This method should provide a component that the user can
 161      * use to manipulate the settings of a concrete configurable
 162      * filter instance.
 163      * <p>NOTE: This method will always be called on the event
 164      *   dispatch thread.
 165      * @return A component that the user can use to reconfigure the
 166      *         filter.
 167      * @see #commitEditorSettings
 168      * @see #resetEditorSettings
 169      */
 170     abstract JComponent getEditorPane();
 171 
 172     /**
 173      * Commit the settings which are currently in the GUI editor.
 174      * Under successful conditions, the GUI settings are saved into
 175      * the state of this object, saved to disk if necessary, and
 176      * a settings changes is emitted to observers.  If a commit
 177      * operation fails, it is expected that the logical outer container
 178      * around the editor will force the user to cancel or correct
 179      * the settings in the GUI.
 180      * <p>NOTE: This method will always be called on the event
 181      *   dispatch thread.
 182      * @return null if committing was successful, an internationalized
 183      *         string helpful to the
 184      *         user is returned if the current settings are unacceptable.
 185      * @see com.sun.javatest.ObservableTestFilter#notifyUpdated
 186      */
 187     abstract String commitEditorSettings();
 188 
 189     /**
 190      * Reset the editor to the settings which reflect the last
 191      * committed state.  This method will typically be called if the
 192      * user explicitly asks to restore the settings, or the user cancels
 193      * the editing operation.  No filter observer traffic is generated.
 194      * <p>NOTE: This method will always be called on the event
 195      *   dispatch thread.
 196      */
 197     abstract void resetEditorSettings();
 198 
 199     /**
 200      * Does the editor have any uncommitted changes?
 201      */
 202     abstract boolean isEditorChanged();
 203 
 204     protected String instanceName;
 205     protected ExecModel execModel;
 206     protected static final String INSTANCE_KEY = "instanceName";
 207     private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(ConfigurableTestFilter.class);
 208 }
 209