View Javadoc

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 }