View Javadoc

1   /*
2    *  
3    *  Fosstrak LLRP Commander (www.fosstrak.org)
4    * 
5    *  Copyright (C) 2008 ETH Zurich
6    *
7    *  This program is free software: you can redistribute it and/or modify
8    *  it under the terms of the GNU General Public License as published by
9    *  the Free Software Foundation, either version 3 of the License, or
10   *  (at your option) any later version.
11   *
12   *  This program is distributed in the hope that it will be useful,
13   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   *  GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License
18   *  along with this program.  If not, see <http://www.gnu.org/licenses/> 
19   *
20   */
21  
22  package org.fosstrak.llrp.commander.preferences.pref;
23  
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.apache.log4j.Logger;
28  import org.eclipse.core.runtime.IStatus;
29  import org.eclipse.core.runtime.Status;
30  import org.eclipse.jface.dialogs.ErrorDialog;
31  import org.eclipse.jface.preference.FieldEditor;
32  import org.eclipse.swt.SWT;
33  import org.eclipse.swt.events.SelectionAdapter;
34  import org.eclipse.swt.events.SelectionEvent;
35  import org.eclipse.swt.graphics.Font;
36  import org.eclipse.swt.layout.GridData;
37  import org.eclipse.swt.layout.GridLayout;
38  import org.eclipse.swt.widgets.Button;
39  import org.eclipse.swt.widgets.Combo;
40  import org.eclipse.swt.widgets.Composite;
41  import org.eclipse.swt.widgets.Control;
42  import org.eclipse.swt.widgets.Group;
43  import org.eclipse.swt.widgets.Label;
44  import org.eclipse.swt.widgets.Shell;
45  import org.eclipse.swt.widgets.Text;
46  import org.fosstrak.llrp.adaptor.AdaptorManagement;
47  import org.fosstrak.llrp.client.Repository;
48  import org.fosstrak.llrp.client.RepositoryFactory;
49  import org.fosstrak.llrp.client.repository.sql.MySQLRepository;
50  import org.fosstrak.llrp.client.repository.sql.PostgreSQLRepository;
51  import org.fosstrak.llrp.commander.LLRPPlugin;
52  import org.fosstrak.llrp.commander.ResourceCenter;
53  import org.fosstrak.llrp.commander.preferences.PreferenceConstants;
54  import org.llrp.ltk.generated.messages.RO_ACCESS_REPORT;
55  
56  /**
57   * An extension of the {@link FieldEditor} supporting the grouping of several 
58   * preferences into a nice group box. 
59   * @author sawielan
60   *
61   */
62  public class GroupedStringFieldEditor extends FieldEditor  {
63  	
64  	// the top level widget holding the whole graphical representation of the 
65  	// preferences.
66  	private Composite groupedFields;
67  	
68  	// how many columns to use in the groupedFields widget.
69  	private int numColumns = 1;
70  	
71  	/** index of the text label in the preferencesLabelsAndNames array. */
72  	public static final int INDEX_LABEL = 0;
73  	
74  	/** index of the preference name in the preferencesLabelsAndNames array. */
75  	public static final int INDEX_PREF_NAME = 1;
76  	
77  	// the preferences widgets.
78  	private Text[] preferences;
79  	
80  	// the label widgets.
81  	private Label[] preferencesLabels;
82  	
83  	// the values of the preferences read from the preferences store.
84  	private String[] preferencesValues;
85  	
86  	// a 2D array holding the labels and the names of the preferences.
87  	private String[][] preferencesLabelsAndNames;
88  	
89  	// a handle to the repository (if test and switch is used).
90  	private Repository repository = null;
91  	
92  	// log4j instance.
93  	private static Logger log = Logger.getLogger(GroupedStringFieldEditor.class);
94  	
95  	
96  	/**
97  	 * A {@link FieldEditor} supporting the grouping of several preferences 
98  	 * into a nice group box. 
99  	 * @param labelText the text of the group box (example the title).
100 	 * @param preferencesLabelsAndNames a 2D array providing the labels for the 
101 	 * preferences in the first column, and the preferences names in the 
102 	 * second column.<br/>
103 	 * <h3>Example</h3>
104 	 * <code>new String[][] {</code><br/>
105 	 * <code>&nbsp;&nbsp;{"Implementor", PreferenceConstants.P_EXT_DB_IMPLEMENTOR },</code><br/>
106 	 * <code>&nbsp;&nbsp;{"JDBC String", PreferenceConstants.P_EXT_DB_JDBC}</code><br/>
107 	 * <code>}</code>
108 	 * @param parent the parent widget of this editor.
109 	 */
110 	public GroupedStringFieldEditor(String labelText, 
111 			String[][] preferencesLabelsAndNames, Composite parent) {
112 		
113 		this.preferencesLabelsAndNames = preferencesLabelsAndNames;
114 		setLabelText(labelText);
115 		this.numColumns = 2;
116 		createControl(parent);
117 	}
118 	
119 	/**
120 	 * searches for a preference name in the preferences table.
121 	 * @param prefName the name of the preference to search.
122 	 * @return -1 if preference was not found, the index otherwise.
123 	 */
124 	private int getPrefIndex(String prefName) {
125 		for (int i=0; i<preferencesLabelsAndNames.length; i++) {
126 			if (preferencesLabelsAndNames[i][INDEX_PREF_NAME].equals(prefName)) {
127 				return i;
128 			}
129 		}
130 		return -1;
131 	}
132 	
133 	/**
134 	 * @return a hash map containing the settings for the repository creation.
135 	 */
136 	private Map<String, String> prepArgs() {
137 		Map<String, String> args = new HashMap<String, String> ();
138   	  	args.put(
139   			  RepositoryFactory.ARG_WIPE_DB,
140   			  String.format("%b", false));
141   	  	
142   	  	args.put(
143   			  RepositoryFactory.ARG_WIPE_RO_ACCESS_REPORTS_DB, 
144   			  String.format("%b", false));
145   	  	
146   	  	args.put(RepositoryFactory.ARG_USERNAME,
147   			  preferences[getPrefIndex(PreferenceConstants.P_EXT_DB_USERNAME)]
148   			              .getText());
149   	  	
150   	  	args.put(RepositoryFactory.ARG_PASSWRD,
151   			  preferences[getPrefIndex(PreferenceConstants.P_EXT_DB_PWD)]
152   			              .getText());
153   	  	
154   	  	args.put(RepositoryFactory.ARG_JDBC_STRING,
155   			  preferences[getPrefIndex(PreferenceConstants.P_EXT_DB_JDBC)]
156   			              .getText());
157   	  	
158   	  	args.put(RepositoryFactory.ARG_DB_CLASSNAME,
159   			  preferences[getPrefIndex(PreferenceConstants.P_EXT_DB_IMPLEMENTOR)]
160   			              .getText());
161   	  	return args;
162 	}
163 	
164 	/**
165 	 * create the group providing the entries.
166 	 * @param parent the parent of this widget.
167 	 * @return a composite widget holding all the graphical elements.
168 	 */
169 	public Composite getDBFieldControl(Composite parent) {
170 		if (null == groupedFields) {
171 			Font font = parent.getFont();
172 			
173 			// create a nice group box (with the nice border around it).
174 			Group group = new Group(parent, SWT.NONE);
175 			group.setFont(font);
176 			String text = getLabelText();
177 			if (null != text) {
178 				group.setText(text);
179 			} 
180 			groupedFields = group;
181 			GridLayout layout = new GridLayout();
182 			layout.horizontalSpacing = HORIZONTAL_GAP;
183 			layout.numColumns = numColumns;
184 			groupedFields.setLayout(layout);
185 
186 			final Shell shell = parent.getShell();
187 			final Button buttonSwitch = new Button(groupedFields, SWT.BUTTON1);
188 			buttonSwitch.setEnabled(false);
189 			buttonSwitch.setText("Switch configuration");
190 			buttonSwitch.addSelectionListener(new SelectionAdapter() {
191 			      public void widgetSelected(SelectionEvent e) {
192 			    	  // try to open the repository. if it works out, switch it.
193 							
194 			    	  try {
195 						repository = RepositoryFactory.create(
196 								prepArgs());
197 						buttonSwitch.setEnabled(false);
198 					
199 						Repository old = ResourceCenter.getInstance().
200 							setRepository(repository);
201 						if (null != old.getROAccessRepository()) {
202 							AdaptorManagement.getInstance().deregisterPartialHandler(
203 									old.getROAccessRepository(), RO_ACCESS_REPORT.class);
204 						}
205 						// stop the old repository
206 						try {
207 							old.close();
208 						} catch (Exception repoE) {
209 							log.error("Old repository could not be stopped.");
210 						}
211 					} catch (Exception e1) {
212 						IStatus status = new Status(
213 								IStatus.ERROR, LLRPPlugin.PLUGIN_ID, 
214 								"LLRP Repository Error.", e1);
215 						ErrorDialog.openError(shell, 
216 								"Repository Error", e1.getMessage(), status);
217 						repository = null;
218 					}
219 			      }
220 			    });
221 			
222 			final Button buttonTest = new Button(groupedFields, SWT.BUTTON1);
223 			buttonTest.setText("Test configuration");
224 			buttonTest.addSelectionListener(new SelectionAdapter() {
225 			      public void widgetSelected(SelectionEvent e) {
226 			    	  // try to open the repository. if it works out, switch it.
227 			    	  Map<String, String> args = prepArgs();
228 			    	  if (args.get(RepositoryFactory.ARG_DB_CLASSNAME).
229 			    			  equals(
230 			    					  ResourceCenter.getInstance()
231 			    					  .getRepository().getClass().getName())) {
232 			    		  log.debug("We not allow to set the same repository.");
233 			    		  String notice = "Your selection is currently in use.";
234 			    		  IStatus status = new Status(
235 									IStatus.INFO, LLRPPlugin.PLUGIN_ID, 
236 									notice);
237 							ErrorDialog.openError(shell, 
238 									"Please Notice: " + notice, 
239 									notice, 
240 									status);
241 						return;
242 					  }
243 							
244 			    	  try {
245 						repository = RepositoryFactory.create(
246 								args);
247 						repository.close();
248 						repository = null;
249 						buttonSwitch.setEnabled(true);
250 					} catch (Exception e1) {
251 						IStatus status = new Status(
252 								IStatus.ERROR, LLRPPlugin.PLUGIN_ID, 
253 								"LLRP Repository Error.", e1);
254 						ErrorDialog.openError(shell, 
255 								"Repository Error", e1.getMessage(), status);
256 						repository = null;
257 					}
258 			      }
259 			    });
260 			
261 		
262 			// create the graphical representation of the labels and the 
263 			// preferences.
264 			final int len = preferencesLabelsAndNames.length;
265 			preferences = new Text[len];
266 			preferencesLabels = new Label[len];
267 			for (int i=0; i<len; i++) {
268 				
269 				if (preferencesLabelsAndNames[i][INDEX_PREF_NAME].equals(
270 						PreferenceConstants.P_EXT_DB_IMPLEMENTOR)) {
271 					// add some hints.
272 					addImplementorHints(groupedFields);
273 				} else if (preferencesLabelsAndNames[i][INDEX_PREF_NAME].equals(
274 						PreferenceConstants.P_EXT_DB_JDBC)) {
275 					// add some hints.
276 					addJDBCHints(groupedFields);
277 				}
278 				
279 				Label lbl = new Label(groupedFields, SWT.NONE);
280 				lbl.setFont(font);
281 				// add a nice : if not already provided by the label itself
282 				String t = preferencesLabelsAndNames[i][INDEX_LABEL];
283 				if (!t.endsWith(":")) {
284 					t += ":";
285 				}
286 				lbl.setText(t);
287 				preferencesLabels[i] = lbl;
288 				
289 				Text txt = new Text(groupedFields, SWT.BORDER);
290 				txt.setFont(font);
291 				// create a grid data element filling up the margin with the 
292 				// text field so it fills out the whole space.
293 				GridData gd = new GridData();
294 				gd.horizontalSpan = numColumns - 1;
295 				gd.horizontalAlignment = GridData.FILL;
296 				gd.grabExcessHorizontalSpace = true;
297 				txt.setLayoutData(gd);
298 				preferences[i] = txt;
299 			}
300 		} else {
301 			checkParent(groupedFields, parent);
302 		}
303 		return groupedFields;
304 	}
305 	
306 	private void addJDBCHints(Composite parent) {
307 		Label hints = new Label(parent, SWT.NONE);
308 		hints.setText("Examples: ");
309 		
310 		final Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
311 		String[] items = new String [] {
312 				MySQLRepository.JDBC_STR,
313 				PostgreSQLRepository.JDBC_STR
314 		};
315 		combo.setItems(items);
316 		combo.setBounds(0, 0, 200, 20);
317 		combo.addSelectionListener(new SelectionAdapter() {
318 		      public void widgetSelected(SelectionEvent e) {
319 		    	  preferences[
320     	              	getPrefIndex(PreferenceConstants.P_EXT_DB_JDBC)
321     	              	].setText(combo.getItem(combo.getSelectionIndex()));
322 		      }
323 		    });
324 	}
325 
326 	private void addImplementorHints(Composite parent) {
327 		Label hints = new Label(parent, SWT.NONE);
328 		hints.setText("Examples: ");
329 		
330 		final Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
331 		String[] items = new String [] {
332 			MySQLRepository.class.getName(),
333 			PostgreSQLRepository.class.getName()
334 		};
335 		combo.setItems(items);
336 		combo.setBounds(0, 0, 200, 20);
337 		combo.addSelectionListener(new SelectionAdapter() {
338 		      public void widgetSelected(SelectionEvent e) {
339 		    	  preferences[
340     	              	getPrefIndex(PreferenceConstants.P_EXT_DB_IMPLEMENTOR)
341     	              	].setText(combo.getItem(combo.getSelectionIndex()));
342 		      }
343 		    });
344 	}
345 
346 	@Override
347 	protected void createControl(Composite parent) {
348 		GridLayout layout = new GridLayout();
349 		layout.numColumns = getNumberOfControls();
350 		layout.marginWidth = 0;
351 		layout.marginHeight = 0;
352 		layout.horizontalSpacing = HORIZONTAL_GAP;
353 		parent.setLayout(layout);
354 		doFillIntoGrid(parent, layout.numColumns);
355 	}
356 
357 	@Override
358 	protected void adjustForNumColumns(int numColumns) {
359 		((GridData)groupedFields.getLayoutData()).horizontalSpan = numColumns;
360 	}
361 
362 	@Override
363 	protected void doFillIntoGrid(Composite parent, int numColumns) {
364 		Control control = getDBFieldControl(parent);
365 		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
366 		control.setLayoutData(gd);
367 	}
368 
369 	@Override
370 	protected void doLoad() {
371 		final int len = preferencesLabelsAndNames.length;
372 		preferencesValues = new String[len];
373 		for (int i=0; i<len; i++) {
374 			preferencesValues[i] = getPreferenceStore().getString(
375 					preferencesLabelsAndNames[i][INDEX_PREF_NAME]);
376 			preferences[i].setText(preferencesValues[i]);
377 		}
378 	}
379 
380 	@Override
381 	protected void doLoadDefault() {
382 		final int len = preferencesLabelsAndNames.length;
383 		preferencesValues = new String[len];
384 		for (int i=0; i<len; i++) {
385 			preferencesValues[i] = getPreferenceStore().getDefaultString(
386 					preferencesLabelsAndNames[i][INDEX_PREF_NAME]);
387 			preferences[i].setText(preferencesValues[i]);
388 		}
389 	}
390 	
391 	@Override
392 	protected void doStore() {
393 		final int len = preferencesLabelsAndNames.length;
394 		for (int i=0; i<len; i++) {
395 			getPreferenceStore().setValue(
396 					preferencesLabelsAndNames[i][INDEX_PREF_NAME], 
397 					preferences[i].getText());
398 		}
399 	}
400 
401 	@Override
402 	public int getNumberOfControls() {
403 		return 1;
404 	}
405 }