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.dialogs;
23  
24  import java.rmi.RemoteException;
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.HashSet;
28  import java.util.Iterator;
29  import java.util.Map;
30  import java.util.Set;
31  
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.Color;
36  import org.eclipse.swt.graphics.Point;
37  import org.eclipse.swt.graphics.Rectangle;
38  import org.eclipse.swt.layout.GridData;
39  import org.eclipse.swt.layout.GridLayout;
40  import org.eclipse.swt.widgets.Button;
41  import org.eclipse.swt.widgets.Composite;
42  import org.eclipse.swt.widgets.Control;
43  import org.eclipse.swt.widgets.Event;
44  import org.eclipse.swt.widgets.Label;
45  import org.eclipse.swt.widgets.List;
46  import org.eclipse.swt.widgets.Listener;
47  import org.eclipse.swt.widgets.ProgressBar;
48  import org.eclipse.swt.widgets.Shell;
49  import org.eclipse.swt.widgets.Table;
50  import org.eclipse.swt.widgets.TableColumn;
51  import org.eclipse.swt.widgets.TableItem;
52  import org.eclipse.swt.widgets.Text;
53  import org.fosstrak.llrp.adaptor.Adaptor;
54  import org.fosstrak.llrp.adaptor.AdaptorManagement;
55  import org.fosstrak.llrp.adaptor.exception.LLRPRuntimeException;
56  import org.fosstrak.llrp.commander.ResourceCenter;
57  import org.llrp.ltk.types.LLRPMessage;
58  
59  /**
60   * This Dialog will be triggered by the context menu from <code>LLRPEditor</code>
61   * User pick up the readers to issue the LLRP messages.
62   *
63   * @author Haoning Zhang
64   * @author sawielan
65   * @version 1.0
66   */
67  public class SendMessageDialog extends org.eclipse.jface.dialogs.Dialog {
68  	
69  	// the previously selected readers
70  	private Map<String, Set<String> > previouslySelected = 
71  		new HashMap<String, Set<String> > ();
72  	
73  	private ProgressBar progressBar;
74  	
75  	private List outputList;
76  	
77  	private Table tblReaders;
78  	
79  	private Text txtComment;
80  	
81  	private static SendMessageDialog instance;
82  	
83  	/**
84  	 * Default Constructor
85  	 * 
86  	 * @param aShell
87  	 */
88  	private SendMessageDialog(Shell aShell) {
89  		super(aShell);
90  	}
91  	
92  	public static SendMessageDialog getInstance(Shell aShell) {
93  		if (null == instance) {
94  			instance = new SendMessageDialog(aShell);
95  		} 
96  
97  		return instance;
98  	}
99  	
100 
101 	/**
102 	 * Initialize the GUI components.
103 	 */
104 	protected Control createContents(Composite parent) {
105 		
106 		String fileName = ResourceCenter.getInstance().getCurrentFileName();
107 		
108 		parent.getShell().setLayout(new GridLayout(2, false));
109 		parent.getShell().setText("Sending " + fileName);
110 		
111 		GridData gridText = new GridData(GridData.FILL_HORIZONTAL);
112 		gridText.horizontalSpan = 2;
113 		gridText.heightHint = 15;
114 		gridText.widthHint = 400;
115 		
116 		GridData gridList = new GridData(GridData.FILL_HORIZONTAL);
117 		gridList.horizontalSpan = 2;
118 		gridList.heightHint = 180;
119 		
120 		GridData gridComment = new GridData(GridData.FILL_HORIZONTAL);
121 		gridComment.horizontalSpan = 2;
122 		gridComment.heightHint = 18;
123 		
124 		GridData gridOutput = new GridData(GridData.FILL_HORIZONTAL);
125 		gridOutput.horizontalSpan = 2;
126 		gridOutput.heightHint = 100;
127 		
128 		GridData gridBar = new GridData(GridData.FILL_HORIZONTAL);
129 		gridBar.horizontalSpan = 2;
130 		gridBar.heightHint = 15;
131 		
132 		GridData gridButton = new GridData(GridData.FILL_BOTH);
133 		gridButton.horizontalSpan = 1;
134 		gridButton.heightHint = 25;
135 		
136 		Rectangle shellBounds = parent.getShell().getShell().getBounds();
137         Point dialogSize = parent.getShell().getSize();
138 
139         this.getShell().setLocation(shellBounds.x + (shellBounds.width - dialogSize.x) / 2,
140           shellBounds.y + (shellBounds.height - dialogSize.y) / 2);
141         
142         
143         final Label lblReaders = new Label(parent, SWT.NONE);
144         lblReaders.setLayoutData(gridText);
145         lblReaders.setText("Select Readers:");
146         
147         tblReaders = new Table (parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION);
148 		tblReaders.setLayoutData(gridList);
149 		tblReaders.setBounds (0, 0, 300, 200);
150 		tblReaders.setLinesVisible (true);
151 		tblReaders.setHeaderVisible (true);
152 		
153 		TableColumn columnAdapter = new TableColumn (tblReaders, SWT.NONE);
154 		columnAdapter.setText ("Adapter");
155 		TableColumn columnReader = new TableColumn (tblReaders, SWT.NONE);
156 		columnReader.setText ("Reader");
157 
158 		try {
159 			Iterator<String> i = AdaptorManagement.getInstance().getAdaptorNames().iterator();
160 			while (i.hasNext()) {
161 				Adaptor adaptor = AdaptorManagement.getInstance().getAdaptor(i.next());
162 
163 				Iterator<String> j = adaptor.getReaderNames().iterator();
164 				while (j.hasNext()) {
165 					String readerName = j.next();
166 					if (adaptor.getReader(readerName).isConnected()) {
167 						
168 						TableItem item = new TableItem (tblReaders, 0);
169 						String adapter = adaptor.getAdaptorName();
170 						item.setText(0, adapter);
171 						item.setText(1, readerName);
172 					}
173 				}
174 			}
175 		} catch (LLRPRuntimeException llrpe) {
176 			llrpe.printStackTrace();
177 		} catch (RemoteException re) {
178 			re.printStackTrace();
179 		}
180 		
181 		// for all the currently available readers, check if they have been
182 		// selected during the last send action.
183 		ArrayList<Integer> selected = new ArrayList<Integer> ();
184 		// check, if we need to preselect it
185 		for (int i=0; i<tblReaders.getItemCount(); i++) {
186 			TableItem item = tblReaders.getItem(i);
187 			if (wasSelected(item.getText(0), item.getText(1))) {
188 				selected.add(i);
189 			}
190 		}
191 		previouslySelected = new HashMap<String, Set<String>> ();
192 		
193 		columnAdapter.pack();
194 		columnReader.pack();
195 		
196 		if (selected.size() > 0) {
197 			int [] selectionArray = new int[selected.size()];
198 			for (int i=0; i<selectionArray.length; i++) {
199 				selectionArray[i] = selected.get(i);
200 			}
201 			tblReaders.setSelection(selectionArray);
202 		}
203 		
204 		final Label lblComment = new Label(parent, SWT.NONE);
205 		lblComment.setLayoutData(gridText);
206 		lblComment.setText("Comment:");
207 		
208 		txtComment = new Text(parent, SWT.BORDER);
209 		txtComment.setTextLimit(16);
210 		txtComment.setLayoutData(gridComment);
211 		
212 		final Label lblOutput = new Label(parent, SWT.NONE);
213 		lblOutput.setLayoutData(gridText);
214 		lblOutput.setText("Progress:");
215         
216 		outputList = new List(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
217         outputList.setLayoutData(gridOutput);
218         outputList.setBackground(new Color(parent.getDisplay(), 255, 255, 255));
219         outputList.setForeground(new Color(parent.getDisplay(), 0, 0, 0));
220         
221 		progressBar = new ProgressBar (parent, SWT.SMOOTH);
222 		progressBar.setLayoutData(gridBar);
223 		progressBar.setMinimum(0);
224 		progressBar.setMaximum(100);
225 		progressBar.setSelection(0);
226 
227 		
228 		final Button btnOK = new Button(parent, SWT.PUSH);
229 		btnOK.setText("Send");
230 		btnOK.setLayoutData(gridButton);
231 		btnOK.addSelectionListener(new SelectionAdapter() {
232 		      public void widgetSelected(SelectionEvent e) {
233 		    	  
234 		    	  btnOK.setEnabled(false);
235 		    	  outputList.removeAll();
236 		    	  
237 	    		  if (sendMessage()) {
238 	    			  close();
239 	    		  }
240 	    		  
241 		    	  btnOK.setText("Send Again");
242 		    	  btnOK.setEnabled(true);
243 		      }
244 		    });
245 		
246 		
247 		final Button btnCancel = new Button(parent, SWT.PUSH);
248 		btnCancel.setText("Close");
249 		btnCancel.setLayoutData(gridButton);
250 		btnCancel.addSelectionListener(new SelectionAdapter() {
251 		      public void widgetSelected(SelectionEvent e) {
252 		    	  close();
253 		      }
254 		    });
255 		
256 		if (tblReaders.getSelectionIndices().length == 0) {
257 			btnOK.setEnabled(false);
258 			btnCancel.setFocus();
259 		} else {
260 			btnOK.setEnabled(true);
261 			btnOK.setFocus();
262 		}
263 		
264 		tblReaders.addListener(SWT.Selection, new Listener () {
265 			public void handleEvent (Event e) {
266 				int[] selectedList = tblReaders.getSelectionIndices();
267 				
268 				if ((selectedList == null) || (selectedList.length == 0)) {
269 					btnOK.setEnabled(false);
270 				} else {
271 					btnOK.setEnabled(true);
272 				}
273 			}
274 		});
275 		
276 		tblReaders.addListener(SWT.DefaultSelection, new Listener () {
277 			public void handleEvent (Event e) {
278 				int[] selectedList = tblReaders.getSelectionIndices();
279 				if ((selectedList == null) || (selectedList.length == 0)) {
280 					btnOK.setEnabled(false);
281 				} else {
282 					btnOK.setEnabled(true);
283 				}
284 			}
285 		});
286 		
287 		parent.pack();
288 		return parent;
289 		
290 	}
291 
292 	/**
293 	 * saves the readers selected in the table-readers to the previously 
294 	 * selected data-structure.
295 	 * @param tblReaders the table with the readers.
296 	 * @param selectedList the readers that are currently selected.
297 	 */
298 	private void saveSelectedReaders(Table tblReaders,
299 			int[] selectedList) {
300 		
301 		for (int i=0; i<selectedList.length; i++) {
302 			TableItem item = tblReaders.getItem(selectedList[i]);
303 			add(item.getText(0), item.getText(1));
304 		}
305 	}
306 	
307 	/**
308 	 * add a reader to the set of a given adapter.
309 	 * @param adapter the adapter.
310 	 * @param reader the reader.
311 	 */
312 	private void add(String adapter, String reader) {
313 		Set<String> readers = previouslySelected.get(adapter);
314 		if (null == readers) {
315 			readers = new HashSet<String> ();
316 			previouslySelected.put(adapter, readers);
317 		}
318 		readers.add(reader);
319 	}
320 	
321 	/**
322 	 * check if the reader was previously selected.
323 	 * @param adapter the name of the adapter.
324 	 * @param reader the name of the reader.
325 	 * @return true if previously selected, false otherwise.
326 	 */
327 	private boolean wasSelected(String adapter, String reader) {
328 		Set<String> readers = previouslySelected.get(adapter);
329 		if (null == readers) return false;
330 		
331 		return readers.contains(reader);
332 	}
333 	
334 	private void output(String aLine) {
335 		if (null != outputList) {
336 			outputList.add(aLine);
337 		}
338 	}
339 	
340 	private void setProgress(int aPercent) {
341 		if (aPercent < 0) {
342 			aPercent = 0;
343 		}
344 		
345 		if (aPercent > 100) {
346 			aPercent = 100;
347 		}
348 		
349 		if (null != progressBar) {
350 			progressBar.setSelection(aPercent);
351 		}
352 	}
353 	
354 	private boolean sendMessage() {
355 		
356 		String fileName = ResourceCenter.getInstance().getCurrentFileName();
357 		output("Reading " + fileName + "...");
358 		setProgress(10);
359 		
360 		String xmlContent = ResourceCenter.getInstance().getCurrentFile();
361 		
362 		if ((null == xmlContent) || (xmlContent.equals(""))) {
363 			output("Reading " + fileName + "failed!");
364 			return false;
365 		} else {
366 			output(fileName + " loaded.");
367 			setProgress(30);
368 		}
369 		
370 		LLRPMessage message = ResourceCenter.getInstance().generateLLRPMessage(xmlContent);
371 		if (null == message) {
372 			output("Generate LLRPMessage object failed!");
373 			return false;
374 		} else {
375 			output("LLRPMessage object generated successfully.");
376 			setProgress(60);
377 		}
378 		
379 		int step = progressBar.getMaximum() - progressBar.getSelection();
380 		
381 		int [] selectedList = tblReaders.getSelectionIndices();
382 		// save the selected readers for the next send action.
383 		saveSelectedReaders(tblReaders, selectedList);
384 		if (selectedList.length > 0) {
385 			step = step / selectedList.length;
386 		}
387 		
388 		String comment = "";
389 		
390 		if ((txtComment != null) && (!txtComment.getText().equals(""))) {
391 			comment = txtComment.getText();
392 		}
393 		
394 		for (int i = 0; i < selectedList.length; i++) {
395 			
396 			TableItem item = tblReaders.getItem(selectedList[i]);
397 			ResourceCenter.getInstance().sendMessage(item.getText(0),
398 					item.getText(1), message, comment);
399 			output("Sending to " + item.getText(1) + " @ " + item.getText(0) + "...");
400 			setProgress(progressBar.getSelection() + (i + 1) * step);
401 		}
402 		
403 		return true;
404 	}
405 }