View Javadoc

1   /*
2    * Copyright (C) 2007 ETH Zurich
3    *
4    * This file is part of Fosstrak (www.fosstrak.org).
5    *
6    * Fosstrak is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License version 2.1, as published by the Free Software Foundation.
9    *
10   * Fosstrak is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with Fosstrak; if not, write to the Free
17   * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18   * Boston, MA  02110-1301  USA
19   */
20  
21  package org.fosstrak.epcis.captureclient;
22  
23  import java.awt.BorderLayout;
24  import java.awt.GridBagConstraints;
25  import java.awt.GridBagLayout;
26  import java.awt.Insets;
27  import java.awt.event.ActionEvent;
28  import java.awt.event.ActionListener;
29  import java.awt.event.WindowAdapter;
30  import java.awt.event.WindowEvent;
31  import java.io.PrintWriter;
32  import java.io.StringWriter;
33  import java.util.ArrayList;
34  import java.util.Calendar;
35  import java.util.HashMap;
36  import java.util.Map;
37  
38  import javax.swing.BorderFactory;
39  import javax.swing.Box;
40  import javax.swing.BoxLayout;
41  import javax.swing.ImageIcon;
42  import javax.swing.JButton;
43  import javax.swing.JCheckBox;
44  import javax.swing.JComboBox;
45  import javax.swing.JFrame;
46  import javax.swing.JLabel;
47  import javax.swing.JList;
48  import javax.swing.JOptionPane;
49  import javax.swing.JPanel;
50  import javax.swing.JScrollPane;
51  import javax.swing.JTextArea;
52  import javax.swing.JTextField;
53  import javax.swing.ListSelectionModel;
54  import javax.swing.UIManager;
55  import javax.swing.event.DocumentEvent;
56  import javax.swing.event.DocumentListener;
57  import javax.xml.parsers.DocumentBuilder;
58  import javax.xml.parsers.DocumentBuilderFactory;
59  import javax.xml.parsers.ParserConfigurationException;
60  import javax.xml.transform.OutputKeys;
61  import javax.xml.transform.Transformer;
62  import javax.xml.transform.TransformerException;
63  import javax.xml.transform.TransformerFactory;
64  import javax.xml.transform.dom.DOMSource;
65  import javax.xml.transform.stream.StreamResult;
66  
67  import org.fosstrak.epcis.captureclient.CaptureClientHelper.EpcisEventType;
68  import org.fosstrak.epcis.captureclient.CaptureClientHelper.ExampleEvents;
69  import org.fosstrak.epcis.captureclient.CaptureEvent.BizTransaction;
70  import org.fosstrak.epcis.gui.AuthenticationOptionsChangeEvent;
71  import org.fosstrak.epcis.gui.AuthenticationOptionsChangeListener;
72  import org.fosstrak.epcis.gui.AuthenticationOptionsPanel;
73  import org.w3c.dom.DOMImplementation;
74  import org.w3c.dom.Document;
75  import org.w3c.dom.Element;
76  
77  /**
78   * GUI class for the EPCIS Capture Interface Client. Implements the GUI and the
79   * creation of XML from the GUI data.
80   * 
81   * @author David Gubler
82   */
83  public class CaptureClientGui extends WindowAdapter implements ActionListener, AuthenticationOptionsChangeListener {
84  
85      /**
86       * The client through which the EPCISEvents will be sent to the repository's
87       * Capture Operations Module.
88       */
89      private CaptureClient client;
90  
91      /*
92       * These lists hold the input fields for the BizTransactions. The lists are
93       * modified by the user to allow for as many arguments as the user wants.
94       * Objects may be deleted from these lists by pressing the "-" Button.
95       */
96      private ArrayList<JTextField> mwBizTransTypeFields;
97      private ArrayList<JTextField> mwBizTransIDFields;
98      private ArrayList<JButton> mwBizTransButtons;
99  
100     /* main window */
101     private JFrame mainWindow;
102     private JPanel mwMainPanel;
103     private AuthenticationOptionsPanel mwAuthOptions;
104     private JPanel mwConfigPanel;
105     private JPanel mwEventTypePanel;
106     private JPanel mwEventDataPanel;
107     private JPanel mwEventDataInputPanel;
108     private JPanel mwEventDataExamplesPanel;
109     private JPanel mwButtonPanel;
110     private JLabel mwServiceUrlLabel;
111 
112     private JTextField mwServiceUrlTextField;
113     private JComboBox mwEventTypeChooserComboBox;
114     private JCheckBox mwShowDebugWindowCheckBox;
115 
116     /* the BizTransaction field */
117     private JPanel mwBizTransactionPanel;
118     private JButton mwBizTransactionPlus;
119 
120     /* the event time field */
121     private JLabel mwEventTimeLabel;
122     private JTextField mwEventTimeTextField;
123     private JLabel mwEventTimeZoneOffsetLabel;
124     private JTextField mwEventTimeZoneOffsetTextField;
125 
126     /* the action type drop-down box */
127     private JLabel mwActionLabel;
128     private JComboBox mwActionComboBox;
129 
130     /* fields for the various URIs */
131     private JLabel mwBizStepLabel;
132     private JTextField mwBizStepTextField;
133     private JLabel mwDispositionLabel;
134     private JTextField mwDispositionTextField;
135     private JLabel mwReadPointLabel;
136     private JTextField mwReadPointTextField;
137     private JLabel mwBizLocationLabel;
138     private JTextField mwBizLocationTextField;
139     private JLabel mwBizTransactionLabel;
140     private JTextField mwBizTransactionTextField;
141 
142     /* associated EPCs for object events */
143     private JLabel mwEpcListLabel;
144     private JTextField mwEpcListTextField;
145 
146     /* parent EPC field for aggregation events */
147     private JLabel mwParentIDLabel;
148     private JTextField mwParentIDTextField;
149 
150     /* associated EPCs for aggregation events */
151     private JLabel mwChildEPCsLabel;
152     private JTextField mwChildEPCsTextField;
153 
154     /* EPC class for quantity events */
155     private JLabel mwEpcClassLabel;
156     private JTextField mwEpcClassTextField;
157 
158     /* quantity for quantity events */
159     private JLabel mwQuantityLabel;
160     private JTextField mwQuantityTextField;
161 
162     /* buttons */
163     private JButton mwFillInExampleButton;
164     private JButton mwGenerateEventButton;
165 
166     /** example selection window. */
167     private JFrame exampleWindow;
168 
169     private JPanel ewMainPanel;
170     private JPanel ewListPanel;
171     private JPanel ewButtonPanel;
172     private JList ewExampleList;
173     private JScrollPane ewExampleScrollPane;
174     private JButton ewOkButton;
175 
176     /* debug window */
177     private JFrame debugWindow;
178 
179     private JTextArea dwOutputTextArea;
180     private JScrollPane dwOutputScrollPane;
181     private JPanel dwButtonPanel;
182     private JButton dwClearButton;
183     
184     /**
185      * Constructs a new CaptureClientGui initialized with a default address.
186      */
187     public CaptureClientGui() {
188         this(null);
189     }
190 
191     /**
192      * Constructs a new CaptureClientGui initialized with the given address.
193      * 
194      * @param address
195      *            The address to which the CaptureClient should sent its capture
196      *            events.
197      */
198     public CaptureClientGui(final String address) {
199         this.client = new CaptureClient(address);
200         initWindow();
201     }
202 
203     /**
204      * Initializes the GUI window.
205      */
206     private void initWindow() {
207         JFrame.setDefaultLookAndFeelDecorated(true);
208 
209         mainWindow = new JFrame("EPCIS capture interface client");
210         mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
211         mainWindow.setResizable(false);
212 
213         mwMainPanel = new JPanel();
214         mwMainPanel.setLayout(new BoxLayout(mwMainPanel, BoxLayout.PAGE_AXIS));
215         mwMainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
216 
217         mwConfigPanel = new JPanel(new GridBagLayout());
218         mwMainPanel.add(mwConfigPanel);
219         mwEventTypePanel = new JPanel();
220         mwMainPanel.add(mwEventTypePanel);
221         mwEventDataPanel = new JPanel();
222         mwEventDataPanel.setLayout(new BoxLayout(mwEventDataPanel, BoxLayout.PAGE_AXIS));
223         mwMainPanel.add(mwEventDataPanel);
224         mwButtonPanel = new JPanel();
225         mwMainPanel.add(mwButtonPanel);
226 
227         mwConfigPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Configuration"),
228                 BorderFactory.createEmptyBorder(5, 5, 5, 5)));
229 
230         mwEventTypePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Event type"),
231                 BorderFactory.createEmptyBorder(5, 5, 5, 5)));
232 
233         mwEventDataPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Event data"),
234                 BorderFactory.createEmptyBorder(5, 5, 5, 5)));
235 
236         mwServiceUrlLabel = new JLabel("Capture interface URL: ");
237         mwServiceUrlTextField = new JTextField(client.getCaptureUrl(), 75);
238         mwAuthOptions = new AuthenticationOptionsPanel(this);
239         
240         mwServiceUrlTextField.getDocument().addDocumentListener(new DocumentListener() {
241 
242 			public void changedUpdate(DocumentEvent e) {
243 				configurationChanged(new AuthenticationOptionsChangeEvent(this, isComplete()));
244 			}
245 
246 			public void insertUpdate(DocumentEvent e) {
247 				configurationChanged(new AuthenticationOptionsChangeEvent(this, isComplete()));
248 			}
249 
250 			public void removeUpdate(DocumentEvent e) {
251 				configurationChanged(new AuthenticationOptionsChangeEvent(this, isComplete()));
252 			}
253 			
254 			public boolean isComplete() {
255 				String url = mwServiceUrlTextField.getText();
256 				return url != null && url.length() > 0;
257 			}
258         	
259         });
260 
261         
262         mwShowDebugWindowCheckBox = new JCheckBox("Show debug window", false);
263         mwShowDebugWindowCheckBox.addActionListener(this);
264 
265         GridBagConstraints c = new GridBagConstraints();
266         c.fill = GridBagConstraints.HORIZONTAL;
267         c.insets = new Insets(5, 5, 5, 0);
268         c.weightx = 0;
269         c.gridx = 0;
270         c.gridy = 0;
271         mwConfigPanel.add(mwServiceUrlLabel, c);
272         c.weightx = 1;
273         c.gridx = 1;
274         c.gridy = 0;
275         mwConfigPanel.add(mwServiceUrlTextField, c);
276         c.weightx = 0;
277         c.gridx = 0;
278         c.gridy = 1;
279         c.gridwidth = 2;
280         mwConfigPanel.add(mwAuthOptions, c);
281         c.weightx = 0;
282         c.gridx = 0;
283         c.gridy = 2;
284         mwConfigPanel.add(mwShowDebugWindowCheckBox, c);
285 
286         mwEventTypeChooserComboBox = new JComboBox(EpcisEventType.guiNames());
287         mwEventTypeChooserComboBox.addActionListener(this);
288         mwEventTypePanel.add(mwEventTypeChooserComboBox);
289 
290         mwGenerateEventButton = new JButton("Generate event");
291         mwGenerateEventButton.addActionListener(this);
292         mwButtonPanel.add(mwGenerateEventButton);
293 
294         // instantiate all event data input fields, their default values and
295         // descriptions
296         mwEventTimeLabel = new JLabel("event time");
297         mwEventTimeTextField = new JTextField(CaptureClientHelper.format(Calendar.getInstance()));
298         mwEventTimeTextField.setToolTipText(CaptureClientHelper.toolTipDate);
299 
300         mwEventTimeZoneOffsetLabel = new JLabel("time zone offset");
301         mwEventTimeZoneOffsetTextField = new JTextField(CaptureClientHelper.getTimeZone(Calendar.getInstance()));
302 
303         mwActionLabel = new JLabel("action");
304         mwActionComboBox = new JComboBox(CaptureClientHelper.ACTIONS);
305 
306         mwBizStepLabel = new JLabel("business step");
307         mwBizStepTextField = new JTextField();
308         mwBizStepTextField.setToolTipText(CaptureClientHelper.toolTipUri + CaptureClientHelper.toolTipOptional);
309 
310         mwDispositionLabel = new JLabel("disposition");
311         mwDispositionTextField = new JTextField();
312         mwDispositionTextField.setToolTipText(CaptureClientHelper.toolTipUri + CaptureClientHelper.toolTipOptional);
313 
314         mwReadPointLabel = new JLabel("read point");
315         mwReadPointTextField = new JTextField();
316         mwReadPointTextField.setToolTipText(CaptureClientHelper.toolTipUri + CaptureClientHelper.toolTipOptional);
317 
318         mwBizLocationLabel = new JLabel("business location");
319         mwBizLocationTextField = new JTextField();
320         mwBizLocationTextField.setToolTipText(CaptureClientHelper.toolTipUri + CaptureClientHelper.toolTipOptional);
321 
322         mwBizTransactionLabel = new JLabel("business transaction");
323         mwBizTransactionTextField = new JTextField();
324         mwBizTransactionTextField.setToolTipText(CaptureClientHelper.toolTipUri + CaptureClientHelper.toolTipOptional);
325 
326         mwEpcListLabel = new JLabel("EPCs");
327         mwEpcListTextField = new JTextField();
328         mwEpcListTextField.setToolTipText(CaptureClientHelper.toolTipUris);
329 
330         mwParentIDLabel = new JLabel("parent object");
331         mwParentIDTextField = new JTextField();
332         mwParentIDTextField.setToolTipText(CaptureClientHelper.toolTipUri);
333 
334         mwChildEPCsLabel = new JLabel("child EPCs");
335         mwChildEPCsTextField = new JTextField();
336         mwChildEPCsTextField.setToolTipText(CaptureClientHelper.toolTipUris + CaptureClientHelper.toolTipOptional);
337 
338         mwEpcClassLabel = new JLabel("EPC class");
339         mwEpcClassTextField = new JTextField();
340         mwChildEPCsTextField.setToolTipText(CaptureClientHelper.toolTipUri);
341 
342         mwQuantityLabel = new JLabel("quantity");
343         mwQuantityTextField = new JTextField();
344         mwChildEPCsTextField.setToolTipText(CaptureClientHelper.toolTipInteger);
345 
346         mwBizTransTypeFields = new ArrayList<JTextField>();
347         mwBizTransIDFields = new ArrayList<JTextField>();
348         mwBizTransButtons = new ArrayList<JButton>();
349 
350         mwBizTransactionPanel = new JPanel(new GridBagLayout());
351         ImageIcon tempImageIcon = CaptureClientHelper.getImageIcon("new10.gif");
352         mwBizTransactionPlus = new JButton(tempImageIcon);
353         mwBizTransactionPlus.setMargin(new Insets(0, 0, 0, 0));
354         mwBizTransactionPlus.addActionListener(this);
355 
356         addBizTransactionRow();
357 
358         mwEventDataInputPanel = new JPanel(new GridBagLayout());
359         mwEventDataExamplesPanel = new JPanel(new BorderLayout());
360         mwEventDataPanel.add(mwEventDataInputPanel);
361         mwEventDataPanel.add(mwEventDataExamplesPanel);
362 
363         drawEventDataPanel(EpcisEventType.ObjectEvent);
364         mwFillInExampleButton = new JButton("Fill in example");
365         mwFillInExampleButton.addActionListener(this);
366         mwEventDataExamplesPanel.add(mwFillInExampleButton, BorderLayout.EAST);
367 
368         /* draw window */
369         mainWindow.getContentPane().add(mwMainPanel);
370         mainWindow.pack();
371         mainWindow.setVisible(true);
372 
373         drawDebugWindow();
374     }
375 
376     private void drawEventDataPanel(EpcisEventType eventType) {
377         mwEventDataInputPanel.removeAll();
378 
379         GridBagConstraints c = new GridBagConstraints();
380         c.fill = GridBagConstraints.HORIZONTAL;
381         c.insets = new Insets(10, 5, 5, 0);
382 
383         c.gridy = 0;
384         c.weightx = 0; c.gridx = 0;
385         mwEventDataInputPanel.add(mwEventTimeLabel, c);
386         c.weightx = 1; c.gridx = 1;
387         mwEventDataInputPanel.add(mwEventTimeTextField, c);
388 
389         c.gridy++;
390         c.weightx = 0; c.gridx = 0;
391         mwEventDataInputPanel.add(mwEventTimeZoneOffsetLabel, c);
392         c.weightx = 1; c.gridx = 1;
393         mwEventDataInputPanel.add(mwEventTimeZoneOffsetTextField, c);
394 
395         if (EpcisEventType.ObjectEvent == eventType || EpcisEventType.TransactionEvent == eventType) {
396             c.gridy++;
397             c.weightx = 0; c.gridx = 0;
398             mwEventDataInputPanel.add(mwEpcListLabel, c);
399             c.weightx = 1; c.gridx = 1;
400             mwEventDataInputPanel.add(mwEpcListTextField, c);
401         }
402 
403         if (EpcisEventType.AggregationEvent == eventType || EpcisEventType.TransactionEvent == eventType) {
404             c.gridy++;
405             c.weightx = 0; c.gridx = 0;
406             mwEventDataInputPanel.add(mwParentIDLabel, c);
407             c.weightx = 1; c.gridx = 1;
408             mwEventDataInputPanel.add(mwParentIDTextField, c);
409         }
410         
411         if (EpcisEventType.AggregationEvent == eventType) {
412             c.gridy++;
413             c.weightx = 0; c.gridx = 0;
414             mwEventDataInputPanel.add(mwChildEPCsLabel, c);
415             c.weightx = 1; c.gridx = 1;
416             mwEventDataInputPanel.add(mwChildEPCsTextField, c);
417         }
418         
419         if (EpcisEventType.QuantityEvent == eventType) {
420             c.gridy++;
421             c.weightx = 0; c.gridx = 0;
422             mwEventDataInputPanel.add(mwEpcClassLabel, c);
423             c.weightx = 1; c.gridx = 1;
424             mwEventDataInputPanel.add(mwEpcClassTextField, c);
425 
426             c.gridy++;
427             c.weightx = 0; c.gridx = 0;
428             mwEventDataInputPanel.add(mwQuantityLabel, c);
429             c.weightx = 1; c.gridx = 1;
430             mwEventDataInputPanel.add(mwQuantityTextField, c);
431         } else {
432             c.gridy++;
433             c.weightx = 0; c.gridx = 0;
434             mwEventDataInputPanel.add(mwActionLabel, c);
435             c.weightx = 1; c.gridx = 1;
436             mwEventDataInputPanel.add(mwActionComboBox, c);
437         }
438 
439         c.gridy++;
440         c.weightx = 0; c.gridx = 0;
441         mwEventDataInputPanel.add(mwBizStepLabel, c);
442         c.weightx = 1; c.gridx = 1;
443         mwEventDataInputPanel.add(mwBizStepTextField, c);
444 
445         c.gridy++;
446         c.weightx = 0; c.gridx = 0;
447         mwEventDataInputPanel.add(mwDispositionLabel, c);
448         c.weightx = 1; c.gridx = 1;
449         mwEventDataInputPanel.add(mwDispositionTextField, c);
450 
451         c.gridy++;
452         c.weightx = 0; c.gridx = 0;
453         mwEventDataInputPanel.add(mwReadPointLabel, c);
454         c.weightx = 1; c.gridx = 1;
455         mwEventDataInputPanel.add(mwReadPointTextField, c);
456 
457         c.gridy++;
458         c.weightx = 0; c.gridx = 0;
459         mwEventDataInputPanel.add(mwBizLocationLabel, c);
460         c.weightx = 1; c.gridx = 1;
461         mwEventDataInputPanel.add(mwBizLocationTextField, c);
462 
463         c.gridy++;
464         c.weightx = 0; c.gridx = 0;
465         mwEventDataInputPanel.add(mwBizTransactionLabel, c);
466         c.weightx = 1; c.gridx = 1;
467         mwEventDataInputPanel.add(mwBizTransactionPanel, c);
468     }
469 
470     /**
471      * Sets up the window used to show the debug output.
472      */
473     private void drawDebugWindow() {
474         debugWindow = new JFrame("Debug output");
475         debugWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
476         debugWindow.addWindowListener(this);
477         debugWindow.setLocation(500, 100);
478         debugWindow.setSize(500, 300);
479 
480         dwOutputTextArea = new JTextArea();
481         dwOutputScrollPane = new JScrollPane(dwOutputTextArea);
482         debugWindow.add(dwOutputScrollPane);
483 
484         dwButtonPanel = new JPanel();
485         debugWindow.add(dwButtonPanel, BorderLayout.AFTER_LAST_LINE);
486 
487         dwClearButton = new JButton("Clear");
488         dwClearButton.addActionListener(this);
489         dwButtonPanel.add(dwClearButton);
490     }
491 
492     /**
493      * Sets up the window used to show the list of examples. Can only be open
494      * once.
495      */
496     private void drawExampleWindow() {
497         if (exampleWindow != null) {
498             exampleWindow.setVisible(true);
499             return;
500         }
501         exampleWindow = new JFrame("Choose example");
502         exampleWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
503 
504         ewMainPanel = new JPanel();
505         ewMainPanel.setLayout(new BoxLayout(ewMainPanel, BoxLayout.PAGE_AXIS));
506         exampleWindow.add(ewMainPanel);
507 
508         ewListPanel = new JPanel();
509         ewListPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 5));
510         ewListPanel.setLayout(new BoxLayout(ewListPanel, BoxLayout.PAGE_AXIS));
511 
512         ewButtonPanel = new JPanel();
513         ewButtonPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10));
514         ewButtonPanel.setLayout(new BoxLayout(ewButtonPanel, BoxLayout.LINE_AXIS));
515 
516         ewMainPanel.add(ewListPanel);
517         ewMainPanel.add(ewButtonPanel);
518 
519         ewExampleList = new JList();
520         ewExampleScrollPane = new JScrollPane(ewExampleList);
521         ewListPanel.add(ewExampleScrollPane);
522         ewExampleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
523 
524         String[] exampleList = new String[ExampleEvents.getExamples().size()];
525         for (int i = 0; i < ExampleEvents.getExamples().size(); i++) {
526             exampleList[i] = ExampleEvents.getExamples().get(i).getDescription();
527         }
528         ewExampleList.setListData(exampleList);
529 
530         ewOkButton = new JButton("Fill in");
531         ewOkButton.addActionListener(this);
532         ewButtonPanel.add(Box.createHorizontalGlue());
533         ewButtonPanel.add(ewOkButton);
534         ewButtonPanel.add(Box.createHorizontalGlue());
535 
536         exampleWindow.pack();
537         exampleWindow.setVisible(true);
538     }
539 
540     /**
541      * Event dispatcher. Very simple events may be processed directly within
542      * this method.
543      * 
544      * @param e
545      *            for the Action
546      */
547     public void actionPerformed(final ActionEvent e) {
548         if (e.getSource() == mwEventTypeChooserComboBox) {
549             mwEventTypeChooserComboBoxChanged();
550             return;
551         }
552         if (e.getSource() == mwGenerateEventButton) {
553             mwGenerateEventButtonPressed();
554             return;
555         }
556         if (e.getSource() == mwFillInExampleButton) {
557             drawExampleWindow();
558             return;
559         }
560         if (e.getSource() == ewOkButton) {
561             ewOkButtonPressed();
562             return;
563         }
564         if (e.getSource() == dwClearButton) {
565             dwOutputTextArea.setText("");
566         }
567         if (e.getSource() == mwShowDebugWindowCheckBox) {
568             debugWindow.setVisible(mwShowDebugWindowCheckBox.isSelected());
569             return;
570         }
571         if (e.getSource() == mwBizTransactionPlus) {
572             addBizTransactionRow();
573         }
574         // check, if it is a JButton and second, if its name starts with
575         // "removeBizTransNumber<Number>".
576         if (((JButton) e.getSource()).getName() != null
577                 && ((JButton) e.getSource()).getName().startsWith("removeBizTransNumber")) {
578             removeBizTransactionRow((JButton) e.getSource());
579         }
580     }
581 
582     /**
583      * The user pushed the Ok button in the example window. Apply the chosen
584      * example to the GUI.
585      */
586     private void ewOkButtonPressed() {
587         int selected = ewExampleList.getSelectedIndex();
588         if (selected >= 0) {
589             CaptureEvent ex = ExampleEvents.getExamples().get(selected);
590 
591             mwEventTimeTextField.setText(ex.getEventTime());
592             mwEventTimeZoneOffsetTextField.setText(ex.getEventTimeZoneOffset());
593             if (ex.getAction() >= 0 && ex.getAction() <= 3) {
594                 mwActionComboBox.setSelectedIndex(ex.getAction());
595             }
596             mwBizStepTextField.setText(ex.getBizStep());
597             mwDispositionTextField.setText(ex.getDisposition());
598             mwReadPointTextField.setText(ex.getReadPoint());
599             mwBizLocationTextField.setText(ex.getBizLocation());
600 
601             ArrayList<BizTransaction> bizTrans = new ArrayList<BizTransaction>();
602             bizTrans = ex.getBizTransaction();
603             // erase all what has been.
604             mwBizTransTypeFields = new ArrayList<JTextField>();
605             mwBizTransIDFields = new ArrayList<JTextField>();
606             mwBizTransButtons = new ArrayList<JButton>();
607             int i = 0;
608             for (BizTransaction transaction : bizTrans) {
609                 addBizTransactionRow();
610                 mwBizTransTypeFields.get(i).setText(transaction.getBizTransType());
611                 mwBizTransIDFields.get(i).setText(transaction.getBizTransID());
612                 i++;
613             }
614             drawBizTransaction();
615 
616             mwEpcListTextField.setText(ex.getEpcList());
617             mwChildEPCsTextField.setText(ex.getChildEPCs());
618             mwParentIDTextField.setText(ex.getParentID());
619             mwEpcClassTextField.setText(ex.getEpcClass());
620             if (ex.getQuantity() >= 0) {
621                 mwQuantityTextField.setText((new Integer(ex.getQuantity())).toString());
622             }
623             exampleWindow.setVisible(false);
624             mwEventTypeChooserComboBox.setSelectedIndex(ex.getType());
625         }
626     }
627 
628     /**
629      * The user changed the type of event. Update GUI accordingly.
630      */
631     private void mwEventTypeChooserComboBoxChanged() {
632         /* show the corresponding input mask */
633         switch (mwEventTypeChooserComboBox.getSelectedIndex()) {
634         case 0:
635             drawEventDataPanel(EpcisEventType.ObjectEvent);
636             break;
637         case 1:
638             drawEventDataPanel(EpcisEventType.AggregationEvent);
639             break;
640         case 2:
641             drawEventDataPanel(EpcisEventType.QuantityEvent);
642             break;
643         case 3:
644             drawEventDataPanel(EpcisEventType.TransactionEvent);
645             break;
646         default:
647         }
648         /* update graphics */
649         mainWindow.pack();
650     }
651 
652     /**
653      * The user pushed the Generate event-button. This method converts the data
654      * from the user interface to XML, POSTs it to the server and displays the
655      * answer to the user. It also does some simple client-side checks to see if
656      * all necessary fields are filled.
657      */
658     private void mwGenerateEventButtonPressed() {
659         dwOutputTextArea.setText("");
660         /* used later for user interaction */
661         JFrame frame = new JFrame();
662 
663         try {
664             /* DOM-tree stuff */
665             Document document = null;
666             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
667             DocumentBuilder builder = factory.newDocumentBuilder();
668             DOMImplementation impl = builder.getDOMImplementation();
669 
670             /* temporary element variable */
671             Element element = null;
672 
673             /* create empty document and fetch root */
674             document = impl.createDocument("urn:epcglobal:epcis:xsd:1", "epcis:EPCISDocument", null);
675             Element root = document.getDocumentElement();
676 
677             root.setAttribute("creationDate", CaptureClientHelper.format(Calendar.getInstance()));
678             root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
679             root.setAttribute("xmlns:epcis", "urn:epcglobal:epcis:xsd:1");
680             root.setAttribute("schemaVersion", "1.0");
681             element = document.createElement("EPCISBody");
682             root.appendChild(element);
683             root = element;
684             element = document.createElement("EventList");
685             root.appendChild(element);
686             root = element;
687             element = document.createElement(EpcisEventType.values()[mwEventTypeChooserComboBox.getSelectedIndex()].name());
688             root.appendChild(element);
689             root = element;
690 
691             // eventTime
692             if (!CaptureClientHelper.addEventTime(document, root, mwEventTimeTextField.getText())) {
693                 JOptionPane.showMessageDialog(frame, "Please specify the event time "
694                         + "(e.g. 2005-07-18T17:33:20.231Z)", "Error", JOptionPane.ERROR_MESSAGE);
695                 return;
696             }
697 
698             // eventTimeZoneOffset
699             if (!CaptureClientHelper.addEventTimeZoneOffset(document, root, mwEventTimeZoneOffsetTextField.getText())) {
700                 JOptionPane.showMessageDialog(frame, "Please specify the event timezone offset "
701                         + "(e.g. +00:00 or -06:30)", "Error", JOptionPane.ERROR_MESSAGE);
702                 return;
703             }
704 
705             // recordTime is set by the capture-Interface
706 
707             int index = mwEventTypeChooserComboBox.getSelectedIndex();
708             if (EpcisEventType.fromGuiIndex(index) == EpcisEventType.ObjectEvent) {
709                 if (!CaptureClientHelper.addEpcList(document, root, mwEpcListTextField.getText())) {
710                     JOptionPane.showMessageDialog(frame, "Please specify at least one EPC", "Error",
711                             JOptionPane.ERROR_MESSAGE);
712                     return;
713                 }
714                 CaptureClientHelper.addAction(document, root, (String) mwActionComboBox.getSelectedItem());
715                 CaptureClientHelper.addBizStep(document, root, mwBizStepTextField.getText());
716                 CaptureClientHelper.addDisposition(document, root, mwDispositionTextField.getText());
717                 CaptureClientHelper.addReadPoint(document, root, mwReadPointTextField.getText());
718                 CaptureClientHelper.addBizLocation(document, root, mwBizLocationTextField.getText());
719                 CaptureClientHelper.addBizTransactions(document, root, fromGui(mwBizTransIDFields, mwBizTransTypeFields));
720             } else if (EpcisEventType.fromGuiIndex(index) == EpcisEventType.AggregationEvent) {
721                 if (!CaptureClientHelper.addParentId(document, root, mwParentIDTextField.getText()) && !mwActionComboBox.getSelectedItem().equals("OBSERVE")) {
722                     JOptionPane.showMessageDialog(frame, "Because action is OBSERVE, it's required to "
723                             + "specify a ParentID", "Error", JOptionPane.ERROR_MESSAGE);
724                     return;
725                 }
726                 if (!CaptureClientHelper.addChildEpcList(document, root, mwChildEPCsTextField.getText())) {
727                     JOptionPane.showMessageDialog(frame, "Please specify at least one EPC", "Error",
728                             JOptionPane.ERROR_MESSAGE);
729                     return;
730                 }
731                 CaptureClientHelper.addAction(document, root, (String) mwActionComboBox.getSelectedItem());
732                 CaptureClientHelper.addBizStep(document, root, mwBizStepTextField.getText());
733                 CaptureClientHelper.addDisposition(document, root, mwDispositionTextField.getText());
734                 CaptureClientHelper.addReadPoint(document, root, mwReadPointTextField.getText());
735                 CaptureClientHelper.addBizLocation(document, root, mwBizLocationTextField.getText());
736                 CaptureClientHelper.addBizTransactions(document, root, fromGui(mwBizTransIDFields, mwBizTransTypeFields));
737             } else if (EpcisEventType.fromGuiIndex(index) == EpcisEventType.QuantityEvent) {
738                 if (!CaptureClientHelper.addEpcClass(document, root, mwEpcClassTextField.getText())) {
739                     JOptionPane.showMessageDialog(frame, "Please specify an EPC class (URI)", "Error",
740                             JOptionPane.ERROR_MESSAGE);
741                     return;
742                 }
743                 if (!CaptureClientHelper.addQuantity(document, root, mwQuantityTextField.getText())) {
744                     JOptionPane.showMessageDialog(frame, "Please specify a quantity value (integer number)", "Error",
745                             JOptionPane.ERROR_MESSAGE);
746                     return;
747                 }
748                 CaptureClientHelper.addBizStep(document, root, mwBizStepTextField.getText());
749                 CaptureClientHelper.addDisposition(document, root, mwDispositionTextField.getText());
750                 CaptureClientHelper.addReadPoint(document, root, mwReadPointTextField.getText());
751                 CaptureClientHelper.addBizLocation(document, root, mwBizLocationTextField.getText());
752                 CaptureClientHelper.addBizTransactions(document, root, fromGui(mwBizTransIDFields, mwBizTransTypeFields));
753             } else if (EpcisEventType.fromGuiIndex(index) == EpcisEventType.TransactionEvent) {
754                 if (!CaptureClientHelper.addBizTransactions(document, root, fromGui(mwBizTransIDFields, mwBizTransTypeFields))) {
755                     JOptionPane.showMessageDialog(frame, "Please specify at least one business "
756                             + "transaction (ID, Type)", "Error", JOptionPane.ERROR_MESSAGE);
757                     return;
758                 }
759                 CaptureClientHelper.addParentId(document, root, mwParentIDTextField.getText());
760                 if (!CaptureClientHelper.addEpcList(document, root, mwEpcListTextField.getText())) {
761                     JOptionPane.showMessageDialog(frame, "Please specify at least one EPC", "Error",
762                             JOptionPane.ERROR_MESSAGE);
763                     return;
764                 }
765                 CaptureClientHelper.addAction(document, root, (String) mwActionComboBox.getSelectedItem());
766                 CaptureClientHelper.addBizStep(document, root, mwBizStepTextField.getText());
767                 CaptureClientHelper.addDisposition(document, root, mwDispositionTextField.getText());
768                 CaptureClientHelper.addReadPoint(document, root, mwReadPointTextField.getText());
769                 CaptureClientHelper.addBizLocation(document, root, mwBizLocationTextField.getText());
770             }
771 
772             DOMSource domsrc = new DOMSource(document);
773 
774             StringWriter out = new StringWriter();
775             StreamResult streamResult = new StreamResult(out);
776             TransformerFactory tf = TransformerFactory.newInstance();
777             Transformer serializer = tf.newTransformer();
778 
779             serializer.setOutputProperty(OutputKeys.INDENT, "yes");
780             serializer.transform(domsrc, streamResult);
781 
782             String eventXml = out.toString();
783             String postData = eventXml;
784 
785             dwOutputTextArea.append("sending HTTP POST data:\n");
786             dwOutputTextArea.append(postData);
787 
788             /* connect the service, write out xml and get response */
789             int response = client.capture(postData);
790 
791             if (response == 200) {
792                 JOptionPane.showMessageDialog(frame, "Capture request succeeded.", "Success",
793                         JOptionPane.INFORMATION_MESSAGE);
794             } else {
795                 JOptionPane.showMessageDialog(frame, "Capture request failed (HTTP response code " + response + ").",
796                         "Error", JOptionPane.ERROR_MESSAGE);
797             }
798 
799         } catch (TransformerException te) {
800             JOptionPane.showMessageDialog(frame, te.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
801             StringWriter detailed = new StringWriter();
802             PrintWriter pw = new PrintWriter(detailed);
803             te.printStackTrace(pw);
804             dwOutputTextArea.append(detailed.toString());
805         } catch (ParserConfigurationException pce) {
806             JOptionPane.showMessageDialog(frame, pce.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
807             StringWriter detailed = new StringWriter();
808             PrintWriter pw = new PrintWriter(detailed);
809             pce.printStackTrace(pw);
810             dwOutputTextArea.append(detailed.toString());
811         } catch (CaptureClientException e) {
812             JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
813             StringWriter detailed = new StringWriter();
814             PrintWriter pw = new PrintWriter(detailed);
815             e.printStackTrace(pw);
816             dwOutputTextArea.append(detailed.toString());
817         }
818     }
819 
820     private Map<String, String> fromGui(ArrayList<JTextField> bizTransID, ArrayList<JTextField> bizTransType) {
821         if (bizTransID == null || bizTransType == null) {
822             return null;
823         }
824         Map<String, String> bizTransMap = new HashMap<String, String>(bizTransID.size());
825         for (int i = 0; i < bizTransID.size(); i++) {
826             if (i < bizTransID.size() && i < bizTransType.size()) {
827                 bizTransMap.put(bizTransID.get(i).getText(), bizTransType.get(i).getText());
828             }
829         }
830         return bizTransMap;
831     }
832 
833     /**
834      * Event handler for window manager closing events. Overrides the default,
835      * empty method.
836      * 
837      * @param e
838      *            The WindowEvent.
839      * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
840      */
841     public void windowClosing(final WindowEvent e) {
842         if (e.getSource() == debugWindow) {
843             mwShowDebugWindowCheckBox.setSelected(false);
844             return;
845         }
846     }
847 
848     /**
849      * Adds another row at the end of the Business Transactions.
850      */
851     private void addBizTransactionRow() {
852         JTextField bizTransID = new JTextField();
853         bizTransID.setToolTipText(CaptureClientHelper.toolTipBizTransID);
854         JTextField bizTransType = new JTextField();
855         bizTransType.setToolTipText(CaptureClientHelper.toolTipBizTransType);
856 
857         ImageIcon tempDelIcon = CaptureClientHelper.getImageIcon("delete10.gif");
858         JButton minus = new JButton(tempDelIcon);
859 
860         minus.setMargin(new Insets(0, 0, 0, 0));
861         minus.addActionListener(this);
862 
863         mwBizTransTypeFields.add(bizTransType);
864         mwBizTransIDFields.add(bizTransID);
865         mwBizTransButtons.add(minus);
866 
867         drawBizTransaction();
868     }
869 
870     /**
871      * Removes a row from the Business Transactions.
872      * 
873      * @param button
874      *            The JButton which generated the event.
875      */
876     private void removeBizTransactionRow(final JButton button) {
877         int toRemove = Integer.parseInt(button.getName().substring(button.getName().length() - 1,
878                 button.getName().length()));
879         mwBizTransTypeFields.remove(toRemove);
880         mwBizTransIDFields.remove(toRemove);
881         mwBizTransButtons.remove(toRemove);
882 
883         drawBizTransaction();
884     }
885 
886     /**
887      * After having added or deleted a Row from the BusinessTransactions, it has
888      * to be re-drawn.
889      */
890     private void drawBizTransaction() {
891         GridBagConstraints c = new GridBagConstraints();
892         c.fill = GridBagConstraints.HORIZONTAL;
893         c.insets = new Insets(2, 5, 5, 0);
894 
895         mwBizTransactionPanel.removeAll();
896 
897         int i = 0;
898         c.weightx = 0;
899         c.gridx = 0;
900         c.fill = GridBagConstraints.NONE;
901         for (JButton j : mwBizTransButtons) {
902             // every name from minus-Buttons has
903             // to start with "removeBizTransNumber<Number>"
904             j.setName("removeBizTransNumber" + i);
905             c.gridy = i;
906             mwBizTransactionPanel.add(j, c);
907             i++;
908         }
909 
910         i = 0;
911         c.weightx = 1;
912         c.gridx = 1;
913         c.fill = GridBagConstraints.BOTH;
914         for (JTextField j : mwBizTransIDFields) {
915             c.gridy = i;
916             mwBizTransactionPanel.add(j, c);
917             i++;
918         }
919         i = 0;
920         c.weightx = 1;
921         c.gridx = 2;
922         c.fill = GridBagConstraints.BOTH;
923         for (JTextField j : mwBizTransTypeFields) {
924             c.gridy = i;
925             mwBizTransactionPanel.add(j, c);
926             i++;
927         }
928 
929         c.weightx = 0;
930         c.gridx = 0;
931         c.gridy = i + 1;
932         c.fill = GridBagConstraints.NONE;
933         mwBizTransactionPanel.add(mwBizTransactionPlus, c);
934 
935         // in case of having no BusinessTransactionfields,
936         // we need to insert two "null"-elements that the
937         // plus-Button is left-aligned.
938         if (i == 0) {
939             c.weightx = 1;
940             c.gridx = 1;
941             c.gridy = i + 1;
942             c.fill = GridBagConstraints.BOTH;
943             mwBizTransactionPanel.add(new JPanel(), c);
944             c.weightx = 1;
945             c.gridx = 2;
946             c.gridy = i + 1;
947             mwBizTransactionPanel.add(new JPanel(), c);
948         }
949 
950         mainWindow.pack();
951     }
952 
953     /**
954      * Instantiates a new CaptureClientGui using a look-and-feel that matches
955      * the operating system.
956      * 
957      * @param args
958      *            The address to which the CaptureClient should send the capture
959      *            events. If omitted, a default address will be provided.
960      */
961     public static void main(final String[] args) {
962         try {
963             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
964         } catch (Exception e) {
965             e.printStackTrace();
966         }
967         if (args != null && args.length > 0) {
968             // a default url is given
969             new CaptureClientGui(args[0]);
970         } else {
971             new CaptureClientGui();
972         }
973     }
974 
975 	public void configurationChanged(AuthenticationOptionsChangeEvent ace) {
976         if (ace.isComplete()) {
977         	mwGenerateEventButton.setEnabled(true);
978         	client = new CaptureClient(mwServiceUrlTextField.getText(), mwAuthOptions.getAuthenticationOptions());
979         } else {
980         	mwGenerateEventButton.setEnabled(false);
981         }
982 	}
983 }