1 /* 2 Copyright (C) 2000 - 2007 Grid Systems, S.A. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2, as 6 published by the Free Software Foundation. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 /* 19 * Project: KernelConfigurator 20 * Created on 23-feb-2004 21 * 22 * Copyright (c)2003 Grid Systems 23 */ 24 package com.gridsystems.config; 25 26 import java.util.ResourceBundle; 27 28 /** 29 * Plugin Configurator base class. Subclasses will act as controllers in 30 * an MVC pattern. 31 * 32 * @author <a href="mailto:rruiz@gridsystems.com">Rodrigo Ruiz Aguayo</a> 33 * @version 1.0 34 */ 35 public abstract class Configurator { 36 37 /** 38 * This mode forces NullUI to be used. 39 */ 40 public static final int MODE_SILENT = 0; 41 42 /** 43 * This mode forces SwingUI to be used. 44 */ 45 public static final int MODE_SWING = 1; 46 47 /** 48 * This mode forces ConsoleUI to be used. 49 */ 50 public static final int MODE_CONSOLE = 2; 51 52 /** 53 * Default mode is {@link #MODE_SILENT}. 54 */ 55 private static int mode = MODE_SILENT; 56 57 /** 58 * Path to the kernel context directory. 59 */ 60 private static String contextDir = System.getProperty("kernel.context", 61 "../webapps/kernel"); 62 63 /** 64 * True if the configurator is being closed. 65 */ 66 private static boolean closing = false; 67 68 /** 69 * Name of the user that will start the server. 70 */ 71 private static String username = ""; 72 73 /** 74 * A reference to the internal model. 75 */ 76 private ConfiguratorModel model; 77 78 /** 79 * A reference to the active view. 80 */ 81 private ConfiguratorView view; 82 83 /** 84 * A reference to the bundle name to use for i18n. 85 */ 86 private ResourceBundle bundle; 87 88 /** 89 * The root key to use for this instance i18n bundle keys. 90 */ 91 private String keyBase; 92 93 /** 94 * Instance private mode, used to refresh the view on mode changes. 95 */ 96 private int localMode = MODE_SILENT; 97 98 /** 99 * The error listener. 100 */ 101 private ErrorListener listener; 102 103 /** 104 * Constructor. 105 * 106 * @param bundleName The name of the bundle to use 107 * @param keyBase The root of the bundle keys 108 */ 109 public Configurator(String bundleName, String keyBase) { 110 this.bundle = ResourceBundle.getBundle(bundleName); 111 this.keyBase = keyBase; 112 } 113 114 /** 115 * Constructor. 116 * 117 * @param bundle The bundle to use 118 * @param keyBase The root of the bundle keys 119 */ 120 public Configurator(ResourceBundle bundle, String keyBase) { 121 this.bundle = bundle; 122 this.keyBase = keyBase; 123 } 124 125 /** 126 * Gets a name for this instance. It is extracted from the bundle, 127 * using the key <code>keyBase + ".name"</code> 128 * 129 * @return The name of this instance 130 */ 131 public String getName() { 132 return this.bundle.getString(keyBase + ".name"); 133 } 134 135 /** 136 * Gets a path for this instance. It is extracted from the bundle, 137 * using the key <code>keyBase + ".path"</code>. 138 * <p> 139 * The path syntax is its path in the menu tree, with nodes separated 140 * by dot (.) characters. 141 * 142 * @return The path for this instance in the menu tree 143 */ 144 public String getPath() { 145 return this.bundle.getString(keyBase + ".path"); 146 } 147 148 /** 149 * Gets the resource bundle associated to this configuration instance. 150 * 151 * @return The resource bundle of this instance 152 */ 153 public ResourceBundle getBundle() { 154 return this.bundle; 155 } 156 157 /** 158 * Gets a reference to the model of this configurator. 159 * 160 * @return The model 161 */ 162 public ConfiguratorModel getModel() { 163 return model; 164 } 165 166 /** 167 * Sets the model of this configurator. It SHOULD be called from the 168 * subclass constructor. 169 * 170 * @param model The model 171 */ 172 public void setModel(ConfiguratorModel model) { 173 this.model = model; 174 } 175 176 /** 177 * Sets the global view mode. 178 * 179 * @param mode The new view mode 180 */ 181 public static void setViewMode(int mode) { 182 Configurator.mode = mode; 183 } 184 185 /** 186 * Gets the current global view mode. 187 * 188 * @return The current view mode 189 */ 190 public static int getViewMode() { 191 return Configurator.mode; 192 } 193 194 /** 195 * Sets the username. 196 * @param newUsername the new username 197 */ 198 public static void setUsername(String newUsername) { 199 Configurator.username = newUsername; 200 } 201 202 /** 203 * Gets the username. 204 * @return a String containing the username 205 */ 206 public static String getUsername() { 207 return Configurator.username; 208 } 209 210 /** 211 * Gets the path to the kernel context directory. This method returns 212 * the path <code>../webapps/kernel</code> as its default value. The user can 213 * specify an alternate path by adding <code>-Dkernel.context=[path]</code> to 214 * the command line. 215 * 216 * @return The path to the kernel context directory 217 */ 218 public static String getContextDir() { 219 return contextDir; 220 } 221 222 /** 223 * Gets the view corresponding to the current view mode, or null if no 224 * suitable view is available. 225 * 226 * @return A view for this view mode, or null if it is not supported 227 */ 228 public ConfiguratorView getView() { 229 if (localMode != mode) { 230 localMode = mode; 231 switch (mode) { 232 case MODE_SILENT: 233 view = null; 234 break; 235 case MODE_SWING: 236 view = getSwingView(); 237 break; 238 case MODE_CONSOLE: 239 view = getConsoleView(); 240 break; 241 default: 242 view = null; 243 } 244 245 if (view != null) { 246 view.getValues(model); 247 } 248 } 249 return view; 250 } 251 252 /** 253 * Gets if a view exists for the current mode. 254 * 255 * @return <code>true</code> if this instance defines a view for the current mode 256 */ 257 public boolean hasView() { 258 // The most common case: there are views for both console and Swing modes 259 return mode != MODE_SILENT; 260 } 261 262 /** 263 * Gets a view for {@link #MODE_SWING}. 264 * 265 * @return The view 266 */ 267 protected abstract SwingConfiguratorView getSwingView(); 268 269 /** 270 * Gets a view for {@link #MODE_CONSOLE}. 271 * 272 * @return The view 273 */ 274 protected abstract ConsoleConfiguratorView getConsoleView(); 275 276 /** 277 * Creates a new model instance. 278 * 279 * @return A newly created ConfiguratorModel instance 280 */ 281 protected abstract ConfiguratorModel createModel(); 282 283 /** 284 * Saves the view values into the model, and applies it. 285 * 286 * @throws Exception In case of error during model apply 287 */ 288 public void apply() throws Exception { 289 getView(); 290 291 // Gets the model to apply 292 ConfiguratorModel cmodel = null; 293 if (view != null) { 294 cmodel = createModel(); 295 view.setValues(cmodel); 296 cmodel.validate(); 297 } else { 298 cmodel = this.getModel(); 299 } 300 301 cmodel.store(); 302 cmodel.apply(); 303 304 // Keep the model if no errors 305 this.setModel(cmodel); 306 307 // View update for default values refresh 308 if (view != null) { 309 view.getValues(cmodel); 310 } 311 } 312 313 /** 314 * Cancels the current view changes, and reloads the model values into it. 315 */ 316 public void discard() { 317 view = getView(); 318 getModel(); 319 320 if (view != null) { 321 view.getValues(model); 322 } 323 } 324 325 /** 326 * Sets the error listener of this configurator. 327 * 328 * @param listener The listener 329 */ 330 public void setErrorListener(ErrorListener listener) { 331 this.listener = listener; 332 } 333 334 /** 335 * Notifies the listener about an error. 336 * 337 * @param id The error identifier 338 * @param message The error message 339 * @param add The error action flag 340 */ 341 public void updateError(String id, String message, boolean add) { 342 if (listener != null) { 343 listener.updateError(id, message, add); 344 } 345 } 346 347 /** 348 * Sets if the configurator is being closed. 349 * 350 * @param closing true if and only if the configurator is being closed. 351 */ 352 public static void setClosing(boolean closing) { 353 Configurator.closing = closing; 354 } 355 356 /** 357 * Tells if the configurator is being closed. 358 * 359 * @return true if and only if the configurator is being closed. 360 */ 361 public static boolean isClosing() { 362 return Configurator.closing; 363 } 364 }