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 }