This section contains the code for the P2P Dashboard program. Three Java classes make up the P2P Dashboard sample program: P2PDashboard, the main class; PeerDiscovery, a class that handles local/remote peer discovery management; and GroupDiscovery, a class that handles local/remote group discovery management. Details of the P2PDashboard ClassP2PDashboard.java is the main class that encapsulates all graphical user interface elements, such as the window frame, command buttons, scroll pane, text fields, radio buttons, tree structure, and button groups for the Dashboard, and it directly interfaces with the JXTA platform. P2Pdashboard.java employs the following methods:
P2PDashboard utilizes the following JXTA methods:
Listing 19.1 presents the code for P2PDashboard.java. Listing 19.1 P2PDashboard.javaimport java.awt.Container; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.lang.String; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.DefaultListSelectionModel; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import net.jxta.credential.AuthenticationCredential; import net.jxta.document.StructuredDocument; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.exception.PeerGroupException; import net.jxta.membership.Authenticator; import net.jxta.membership.MembershipService; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.ModuleImplAdvertisement; import net.jxta.protocol.PeerGroupAdvertisement; import net.jxta.protocol.PeerAdvertisement; import net.jxta.impl.protocol.PeerGroupAdv; import net.jxta.impl.protocol.PeerAdv; import net.jxta.impl.id.UUID.PeerID; import net.jxta.impl.id.UUID.PeerGroupID; /* P2P Dashboard application */ public class P2PDashboard extends JFrame { // frame reference for JOptionPane message dialogs private JFrame frame; // group section private JScrollPane groupScrollPane; private JList groupList; private Hashtable groupHT; private JTextField groupAddTextField; private JButton groupAddButton; private JButton groupFlushButton; private JButton groupRemoveButton; private JRadioButton groupLocalRadioButton; private JRadioButton groupRemoteRadioButton; private ButtonGroup groupDiscoveryButtonGroup; private JButton groupDiscoveryButton; // peer section private JScrollPane peerScrollPane; private JList peerList; private JTextField peerAddTextField; private JButton peerAddButton; private JButton peerFlushButton; private JCheckBox peerCheckBox; private JButton peerRemoveButton; private JRadioButton peerLocalRadioButton; private JRadioButton peerRemoteRadioButton; private ButtonGroup peerDiscoveryButtonGroup; private JButton peerDiscoveryButton; private boolean displayPeerGroups; // Default NetPeerGroup and discovery service private static PeerGroup netPeerGroup; private DiscoveryService discovery; private String defaultGroupName; private String defaultPeerName; // peer and group discovery event handlers private PeerDiscovery peerDiscovery; private GroupDiscovery groupDiscovery; /*********************/ /* Dashboard Methods */ /*********************/ /* *Command line arguments */ public static void main(String args[]) { P2PDashboard p2p = new P2PDashboard(); p2p.show(); // setup localPeer in NetPeerGroup p2p.initializeNetPeerGroup(); // prepare peer and group discovery services p2p.initializeDiscovery(); } /* *Create a new P2PDashboard frame. */ public P2PDashboard() { frame = this; // group groupScrollPane = new JScrollPane(); groupList = new JList(new SortedListModel()); groupHT = new Hashtable(); groupAddTextField = new JTextField(); groupAddButton = new JButton(); groupFlushButton = new JButton(); groupRemoveButton = new JButton(); groupLocalRadioButton = new JRadioButton(); groupRemoteRadioButton = new JRadioButton(); groupDiscoveryButtonGroup = new ButtonGroup(); groupDiscoveryButton = new JButton(); // peer peerScrollPane = new JScrollPane(); peerList = new JList(new SortedListModel()); peerAddTextField = new JTextField(); peerAddButton = new JButton(); peerFlushButton = new JButton(); peerCheckBox = new JCheckBox(); peerRemoveButton = new JButton(); peerLocalRadioButton = new JRadioButton(); peerRemoteRadioButton = new JRadioButton(); peerDiscoveryButtonGroup = new ButtonGroup(); peerDiscoveryButton = new JButton(); displayPeerGroups = false; initializeGUIComponents(); configureGroupEvents(); configurePeerEvents(); } /* *P2PDashboard uses this to setup GUI objects and *their properties. */ private void initializeGUIComponents() { Container contentPane = getContentPane(); Insets insets = contentPane.getInsets(); contentPane.setLayout(null); // group section groupScrollPane.setViewportBorder (new TitledBorder("Groups")); groupScrollPane.setViewportView(groupList); contentPane.add(groupScrollPane); groupScrollPane.setBounds(10+insets.left, 10+insets.top, 250, 230); groupAddTextField.setToolTipText("Add a new group"); contentPane.add(groupAddTextField); groupAddTextField.setBounds(10+insets.left, 250+insets.top, 140, 20); groupAddButton.setText("Add"); groupAddButton.setToolTipText("Add a new group"); contentPane.add(groupAddButton); groupAddButton.setBounds(170+insets.left, 250+insets.top, 90, 20); groupFlushButton.setText("Flush"); groupFlushButton.setToolTipText ("Flush local group cache"); contentPane.add(groupFlushButton); groupFlushButton.setBounds(10+insets.left, 280+insets.top, 90, 20); groupRemoveButton.setText("Remove"); groupRemoveButton.setToolTipText("Remove a group"); contentPane.add(groupRemoveButton); groupRemoveButton.setBounds(170+insets.left, 280+insets.top, 90, 20); groupLocalRadioButton.setSelected(true); groupLocalRadioButton.setText("Local"); groupLocalRadioButton.setToolTipText ("Search for local groups"); contentPane.add(groupLocalRadioButton); groupLocalRadioButton.setBounds(10+insets.left, 310+insets.top, 60, 20); groupRemoteRadioButton.setText("Remote"); groupRemoteRadioButton.setToolTipText ("Search for remote groups"); contentPane.add(groupRemoteRadioButton); groupRemoteRadioButton.setBounds(90+insets.left, 310+insets.top, 70, 20); groupDiscoveryButtonGroup.add(groupLocalRadioButton); groupDiscoveryButtonGroup.add(groupRemoteRadioButton); groupDiscoveryButton.setText("Discover"); groupDiscoveryButton.setToolTipText("Find groups"); contentPane.add(groupDiscoveryButton); groupDiscoveryButton.setBounds(170+insets.left, 310+insets.top, 90, 20); // peer section peerScrollPane.setViewportBorder (new TitledBorder("Peers")); peerScrollPane.setViewportView(peerList); contentPane.add(peerScrollPane); peerScrollPane.setBounds(290+insets.left, 10+insets.top, 250, 230); peerAddTextField.setToolTipText("Add a new peer"); contentPane.add(peerAddTextField); peerAddTextField.setBounds(290+insets.left, 250+insets.top, 140, 20); peerAddButton.setText("Add"); peerAddButton.setToolTipText("Add a new peer"); contentPane.add(peerAddButton); peerAddButton.setBounds(450+insets.left, 250+insets.top, 90, 20); peerFlushButton.setText("Flush"); peerFlushButton.setToolTipText ("Flush local peer cache"); contentPane.add(peerFlushButton); peerFlushButton.setBounds(290+insets.left, 280+insets.top, 90, 20); peerCheckBox.setSelected(false); peerCheckBox.setText("Groups"); peerCheckBox.setToolTipText ("Display groups peer is in."); contentPane.add(peerCheckBox); peerCheckBox.setBounds(386+insets.left, 280+insets.top, 60, 20); peerRemoveButton.setText("Remove"); peerRemoveButton.setToolTipText("Remove a peer"); contentPane.add(peerRemoveButton); peerRemoveButton.setBounds(450+insets.left, 280+insets.top, 90, 20); peerLocalRadioButton.setSelected(true); peerLocalRadioButton.setText("Local"); peerLocalRadioButton.setToolTipText ("Search for local peers"); contentPane.add(peerLocalRadioButton); peerLocalRadioButton.setBounds(290+insets.left, 310+insets.top, 60, 20); peerRemoteRadioButton.setText("Remote"); peerRemoteRadioButton.setToolTipText ("Search for remote peers"); contentPane.add(peerRemoteRadioButton); peerRemoteRadioButton.setBounds(370+insets.left, 310+insets.top, 70, 20); peerDiscoveryButtonGroup.add(peerLocalRadioButton); peerDiscoveryButtonGroup.add(peerRemoteRadioButton); peerDiscoveryButton.setText("Discover"); peerDiscoveryButton.setToolTipText("Find peers"); contentPane.add(peerDiscoveryButton); peerDiscoveryButton.setBounds(450+insets.left, 310+insets.top, 90, 20); pack(); setTitle("P2P Dashboard"); setSize(558, 365); setResizable(false); // JFrame event addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { exitForm(evt); } }); } /* P2PDashboard uses this to handle GUI object events. */ private void configureGroupEvents() { // group JList event groupList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); groupList.addListSelectionListener (new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } JList list = (JList)e.getSource(); // whenever a group is selected, // retrieve its corresponding peer list and // display it. if (list.isSelectionEmpty() == false) { String group = (String)list.getSelectedValue(); SortedListModel peers = (SortedListModel) groupHT.get(group); peerList.setModel(peers); } } }); // group Add JButton event groupAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String group = groupAddTextField.getText(); SortedListModel list = null; if (checkAddRules(group) == false) { return; } list = (SortedListModel)groupList.getModel(); // ensure new group does not already exist if (list.contains(group) == false) { list.addElement(group); addGroup(group); SortedListModel slm = new SortedListModel(); groupHT.put(group, slm); groupList.setModel(list); groupList.setSelectedValue(group, true); peerList.clearSelection(); } else { handleError("Group `" + group + "` already in use.", "Invalid group name", null, false); } groupAddTextField.setText(""); } }); // peer Flush JButton event groupFlushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // remove all groups except the netPeerGroup SortedListModel list = (SortedListModel) groupList.getModel(); Enumeration enum = list.elements(); String group = null; while (enum.hasMoreElements()) { group = (String)enum.nextElement(); if (group.equals(defaultGroupName) == false) { list.removeElement(group); groupHT.remove(group); } } groupList.setModel(list); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); // flush actual local group advertisements groupDiscovery.flushGroupInfo(); } }); // group Remove JButton event groupRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String group = (String)groupList.getSelectedValue(); if (group == null || group.equals("") == true || group.equals(defaultGroupName)) { return; } SortedListModel list = (SortedListModel) groupList.getModel(); list.removeElement(group); groupList.setModel(list); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); removeAdvertisement(group, false); } }); // group Discovery JButton event groupDiscoveryButton.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) { // initiate local group discovery if (groupLocalRadioButton.isSelected()) { groupDiscovery.setLocalDiscovery(true); groupDiscovery.run(); } // initiate remote group discovery else if (groupRemoteRadioButton.isSelected()) { groupDiscovery.setLocalDiscovery(false); groupDiscovery.run(); } } }); } /* P2PDashboard uses this to handle peer GUI object events. */ private void configurePeerEvents() { // peer JList event peerList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); peerList.addListSelectionListener (new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { JList list = (JList)e.getSource(); String selectedPeer = (String)list.getSelectedValue(); if (e.getValueIsAdjusting() || displayPeerGroups == false) { return; } // whenever a peer is selected, // retrieve its corresponding group list and // display it. if (list.isSelectionEmpty() == false) { SortedListModel peerInGroup = new SortedListModel(); SortedListModel peers = null; String group = null; Enumeration keys = groupHT.keys(); while (keys.hasMoreElements()) { group = (String)keys.nextElement(); peers = (SortedListModel)groupHT.get(group); if (peers.contains(selectedPeer) == true) { peerInGroup.addElement(group); } } groupList.setModel(peerInGroup); groupList.clearSelection(); } } }); // peer Add JButton event peerAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String peer = peerAddTextField.getText(); String group = (String)groupList.getSelectedValue(); // allow defaultPeerName to be added to new groups if (peer != null && !peer.equals("") && group != null && !group.equals("") && peer.equals(defaultPeerName) && !group.equals(defaultGroupName)) { System.out.println ("Adding " + peer + " to group '" + group + "'"); } // default peer name checking else if (checkAddRules(peer) == false || group == null || group.equals("") == true) { handleError("Invalid peer name.", "Invalid peer ", null, false); return; } // do not allow a peer to be the same name as the // currently selected group if (peer.equals(group)) { handleError("Peer cannot be same name as group.", "Invalid peer ", null, false); return; } // retrieve peer list of currently selected group SortedListModel list = (SortedListModel)peerList.getModel(); // ensure new peer does not already exist if (list.contains(peer) == false) { list.addElement(peer); peerList.setModel(list); groupHT.put(group, list); addPeer(peer); } else { handleError("Peer `" + peer + "` already in use.", "Invalid peer ", null, false); } peerAddTextField.setText(""); } }); // peer Flush JButton event peerFlushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // remove every peer in every group // except defaultPeerName in the netPeerGroup Enumeration keys = groupHT.keys(); Enumeration enum = null; SortedListModel peers = null; String group = null; String peer = null; while (keys.hasMoreElements()) { group = (String)keys.nextElement(); peers = (SortedListModel)groupHT.get(group); enum = peers.elements(); while (enum.hasMoreElements()) { peer = (String)enum.nextElement(); if (peer.equals(defaultPeerName) == true && group.equals(defaultGroupName) == true) { System.out.println (defaultPeerName + " not flushed from " + defaultGroupName); } else peers.removeElement(peer); } groupHT.put(group, peers); } groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); // remove all peer advertisements peerDiscovery.flushPeerInfo(); } }); // peer group display JCheckBox event peerCheckBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { // display all peers from every group // so that when we select a peer, we can // show the groups it belongs to. if (e.getStateChange() == ItemEvent.SELECTED) { displayPeerGroups = true; Enumeration keys = groupHT.keys(); Enumeration enum = null; String group = null; String peer = null; SortedListModel allPeers = new SortedListModel(); SortedListModel peers = null; while (keys.hasMoreElements()) { group = (String)keys.nextElement(); peers = (SortedListModel)groupHT.get(group); enum = peers.elements(); while (enum.hasMoreElements()) { peer = (String)enum.nextElement(); if (allPeers.contains(peer) == false) { allPeers.addElement(peer); } } } peerList.setModel(allPeers); peerList.setSelectedValue(defaultPeerName, true); groupList.clearSelection(); } // remove, leave peer might occur now // so allow a group and a peer to be selected. else { displayPeerGroups = false; Enumeration keys = groupHT.keys(); String group = null; SortedListModel groups = new SortedListModel(); while (keys.hasMoreElements()) { group = (String)keys.nextElement(); groups.addElement(group); } groupList.setModel(groups); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); } } }); // peer Remove JButton event peerRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String group = (String)groupList.getSelectedValue(); String peer = (String)peerList.getSelectedValue(); if (peer == null || peer.equals("") == true || group == null || group.equals("") == true) { handleError("Please unselect the `Groups` check box.!", "Remove failed", null, false); return; } if ((peer.equals(defaultPeerName) == true && group.equals(defaultGroupName) == true)) { handleError("Cannot remove local peer from netPeerGroup!", "Remove failed", null, false); return; } // retrieve peer list of currently selected group SortedListModel list = (SortedListModel) peerList.getModel(); list.removeElement(peer); peerList.setModel(list); groupHT.put(group, list); groupList.setSelectedValue(defaultGroupName, true); peerList.clearSelection(); removeAdvertisement(peer, true); } }); // peer Discovery JButton event peerDiscoveryButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // initiate local peer discovery if (peerLocalRadioButton.isSelected()) { peerDiscovery.setLocalDiscovery(true); peerDiscovery.run(); } // initiate remote peer discovery else if (peerRemoteRadioButton.isSelected()) { peerDiscovery.setLocalDiscovery(false); peerDiscovery.run(); } } }); } /* *Exit the application. */ private void exitForm(WindowEvent e) { System.exit(0); } private void handleError(String msg, String title, Exception e, boolean exitSystem) { if (msg == null || title == null || msg.equals("") == true || title.equals("") == true) return; if (e != null) e.printStackTrace(); JOptionPane.showMessageDialog(frame, msg, title, JOptionPane.ERROR_MESSAGE); if (exitSystem) System.exit(1); } /******************************************/ /* Peer and Group List Validation Methods */ /******************************************/ private boolean checkAddRules(String s) { boolean check = true; if (s == null || s.equals("") == true || s.equals(defaultGroupName) == true|| s.equals(defaultPeerName) == true) { check=false; } return check; } /*****************/ /* JXTA Methods */ /*****************/ /* *Initialize the default NetPeerGroup that our *local peer belongs to. */ public void initializeNetPeerGroup() { try { netPeerGroup = PeerGroupFactory.newNetPeerGroup(); discovery = netPeerGroup.getDiscoveryService(); } catch (PeerGroupException e) { handleError("netPeerGroup creation failed!", "NetPeerGroup", e, true); } // Print out useful local peer/group information System.out.println("JXTA group = " + netPeerGroup.getPeerGroupName()); System.out.println("Group ID = " + netPeerGroup.getPeerGroupID().toString()); System.out.println("Peer name = " + netPeerGroup.getPeerName()); System.out.println("Peer ID = " + netPeerGroup.getPeerID().toString()); System.out.println("\n\n"); } /* *Initialize the peer and group discovery services for *handling local and remote discovery events and messages. */ public void initializeDiscovery() { SortedListModel list = null; //Save default peer and group name defaultGroupName = netPeerGroup.getPeerGroupName(); defaultPeerName = netPeerGroup.getPeerName(); //Group Discovery groupDiscovery = new GroupDiscovery(netPeerGroup, discovery, groupList, defaultGroupName); groupDiscovery.startJxta(); // add netPeerGroup to group list in GUI list = (SortedListModel)groupList.getModel(); list.addElement(defaultGroupName); groupList.setModel(list); // create new peer list for group netPeerGroup list = new SortedListModel(); list.addElement(defaultPeerName); groupHT.put(defaultGroupName, list); groupList.setSelectedValue(defaultGroupName, true); // Peer Discovery peerDiscovery = new PeerDiscovery(netPeerGroup, discovery, peerList, defaultPeerName); peerDiscovery.startJxta(); // Add defaultPeerName to peer list in the GUI list = (SortedListModel)peerList.getModel(); list.addElement(defaultPeerName); peerList.setModel(list); peerList.clearSelection(); } /* *Creates a peer and publishes this peer locally *and remotely. */ public void addPeer(String peer) { // create new peer PeerAdvertisement peerAdv = new PeerAdv(); peerAdv.setName(peer); // using PeerGroupID.defaultNetPeerGroupID because // PeerGroup.getGroupID returns ID and we can't resolve // compilation or runtime issues with using // new PeerID(PeerGroupID) method. // Casting the ID to PeerGroupID will work with new // PeerID(PeerGroupID) but causes runtime // cast class exception. // So we will just default all new peers have // the defaultNetPeerGroupID for their group. PeerID peerID = new PeerID (PeerGroupID.defaultNetPeerGroupID); peerAdv.setPeerID(peerID); peerAdv.setPeerGroupID (PeerGroupID.defaultNetPeerGroupID); //Announce new peer. try { discovery.publish(peerAdv, DiscoveryService.PEER); discovery.remotePublish (peerAdv, DiscoveryService.PEER); } catch (IOException e) { handleError("Adding peer `" + peer + "` failed!", "Adding failed", e, false); } } /* *Remove a peer's credentials from the local cache. */ public void removeAdvertisement(String s, boolean peer) { int type = DiscoveryService.PEER; if (peer == false) { type = DiscoveryService.GROUP; } Enumeration enum = null; PeerGroupAdvertisement groupAdv = null; PeerAdvertisement peerAdv = null; try { enum = discovery.getLocalAdvertisements (type, "Name", s); if (enum.hasMoreElements()) { if (peer == false) { groupAdv = (PeerGroupAdvertisement) enum.nextElement(); discovery.flushAdvertisements (groupAdv.getPeerGroupID().toString(), type); } else { peerAdv = (PeerAdvertisement) enum.nextElement(); discovery.flushAdvertisements (peerAdv.getPeerID().toString(), type); } } } catch (IOException e) { handleError("Remove of peer or group failed!", "Removal failed", e, false); } } /* *Create a new group and publishes this group *locally and remotely. */ public PeerGroup addGroup(String group) { ModuleImplAdvertisement mia = null; PeerGroup peerGroup = null; PeerGroupAdvertisement pga = null; try { // create new group mia = netPeerGroup. getAllPurposePeerGroupImplAdvertisement(); peerGroup = netPeerGroup.newGroup(null, mia, group, group + " description"); // announce new group pga = peerGroup.getPeerGroupAdvertisement(); discovery.publish(pga, DiscoveryService.GROUP); discovery.remotePublish(pga, DiscoveryService.GROUP); netPeerGroup.newGroup(pga); } catch (IOException e) { handleError("Group `" + group + "` could not be added!.", "Exception during group add", e, false); } catch (PeerGroupException e) { handleError("Group `" + group + "` could not be added!.", "Exception during group add", e, false); } catch (Exception e) { handleError("Group `" + group + "` could not be added!.", "Exception during group add", e, false); } return peerGroup; } } Details of the PeerDiscovery ClassThe PeerDiscovery class is responsible for the local and remote discovery of peers, as well as for updating the peer information in the GUI. The PeerDiscovery class implements the Runnable and DiscoveryListener interfaces and the following methods:
Listing 19.2 presents the code for PeerDiscovery.java. Listing 19.2 PeerDiscovery.javaimport java.io.InputStream; import java.io.IOException; import java.io.ByteArrayInputStream; import java.lang.String; import java.util.Enumeration; import javax.swing.JList; import net.jxta.document.Advertisement; import net.jxta.document.AdvertisementFactory; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.discovery.DiscoveryListener; import net.jxta.discovery.DiscoveryEvent; import net.jxta.exception.PeerGroupException; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.DiscoveryResponseMsg; import net.jxta.protocol.PeerAdvertisement; /* *PeerDiscovery *Responsible for local and remote discovery of peers. *Also responsible for updating the peer info in the GUI. */ public class PeerDiscovery implements Runnable, DiscoveryListener { // necessary links to important local peer information private PeerGroup netPeerGroup; private DiscoveryService discovery; private PeerAdvertisement peerAdv; // link to peer GUI list private JList peerList; private String defaultPeerName; // link to GUI discovery selection type (local or remote) private boolean local; /* *Update peer GUI for adding/removing peers */ private void updateGUI(boolean stringCast, Enumeration enum) { String str = null; PeerAdvertisement newAdv = null; MimeMediaType mmt = new MimeMediaType("text/xml"); SortedListModel peers = (SortedListModel)peerList.getModel(); while (enum.hasMoreElements()) { // Processing String objects if (stringCast) { str = (String)enum.nextElement(); try { // create an advertisement for each element newAdv = (PeerAdvertisement) AdvertisementFactory.newAdvertisement (mmt, new ByteArrayInputStream(str.getBytes())); } catch (IOException ioe) { System.out.println ("Error parsing response element!"); ioe.printStackTrace(); continue; } } // Processing PeerAdvertisement objects else { newAdv = (PeerAdvertisement)enum.nextElement(); } System.out.println("Discovered peer = " + newAdv.getName()); // found a new peer, add them to the peerList if (peers.contains(newAdv.getName()) == false) { peers.addElement(newAdv.getName()); System.out.println("Discovered peer = " + newAdv.getName() + " added"); } } // update the GUI peerList.setModel(peers); peerList.setSelectedValue(defaultPeerName, true); } /* *Start JXTA method */ public void startJxta() { // flush local JXTA cache flushPeerInfo(); } /* *Flush local peer cache information */ public void flushPeerInfo() { try { discovery.flushAdvertisements (null, DiscoveryService.PEER); } catch (IOException e) { e.printStackTrace(); } } /* *On demand, discover peers locally or remotely *via a thread. */ public void run() { Enumeration enum = null; SortedListModel peers = (SortedListModel)peerList.getModel(); try { //Add ourselves as a discoverylistener for //discovery response events. discovery.addDiscoveryListener(this); // check local cache for peer if (local) { enum = discovery.getLocalAdvertisements (DiscoveryService.PEER, null, null); if (enum == null || enum.hasMoreElements() == false) { System.out.println ("No local advertisements found"); } System.out.println ("update GUI peer discovery now"); //Update peer list in GUI updateGUI(false, enum); } //Wait 10 seconds per remote discovery else { discovery.getRemoteAdvertisements(null, DiscoveryService.PEER, null, null, 10, this); try { Thread.sleep(10 * 1000); } catch (Exception e) { } } } catch (Exception e) { e.printStackTrace(); } } /* *Handle remote discovery messages. */ public void discoveryEvent(DiscoveryEvent e) { DiscoveryResponseMsg drm = e.getResponse(); String response = drm.getPeerAdv(); InputStream is = null; PeerAdvertisement peerAdv = null; MimeMediaType mmt = new MimeMediaType("text/xml"); try { // create a peer advertisement is = new ByteArrayInputStream(response.getBytes()); peerAdv = (PeerAdvertisement) AdvertisementFactory.newAdvertisement(mmt, is); System.out.println ("[ Received discovery response [" + drm.getResponseCount() + " elements] from peer : " + peerAdv.getName() + " ]"); } catch (IOException ioe) { System.out.println("Error parsing remote peer's advertisement!"); ioe.printStackTrace(); return; } // update peers in GUI updateGUI(true, drm.getResponses()); } /* *set discovery to be local or remote *local = true > search is local *local = false > search is remote */ public void setLocalDiscovery(boolean local) { this.local = local; } /* *Creates new PeerDiscovery object. */ public PeerDiscovery(PeerGroup netPeerGroup, DiscoveryService discovery, JList peerList, String defaultPeerName) { this.netPeerGroup = netPeerGroup; this.discovery = discovery; this.peerList = peerList; this.defaultPeerName = defaultPeerName; local = true; } } Details of the GroupDiscovery.java ClassThe GroupDiscovery class is responsible for handling local and remote discovery of groups, as well as updating the group information on the GUI. The GroupDiscovery class implements the Runnable and DiscoveryListener interfaces. It uses the following methods:
Listing 19.3 presents the code for GroupDiscovery.java. Listing 19.3 GroupDiscovery.javaimport java.io.InputStream; import java.io.IOException; import java.io.ByteArrayInputStream; import java.lang.String; import java.util.Enumeration; import javax.swing.JList; import net.jxta.document.Advertisement; import net.jxta.document.AdvertisementFactory; import net.jxta.document.MimeMediaType; import net.jxta.discovery.DiscoveryService; import net.jxta.discovery.DiscoveryListener; import net.jxta.discovery.DiscoveryEvent; import net.jxta.exception.PeerGroupException; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupFactory; import net.jxta.protocol.DiscoveryResponseMsg; import net.jxta.protocol.PeerAdvertisement; import net.jxta.protocol.PeerGroupAdvertisement; /* *GroupDiscovery *Responsible for local and remote discovery of groups. *Also responsible for updating the group information *in the GUI. */ public class GroupDiscovery implements Runnable, DiscoveryListener { // necessary links to important group information private PeerGroup netPeerGroup; private DiscoveryService discovery; private PeerAdvertisement peerAdv; // link to group tree GUI private JList groupList; private String defaultGroupName; // link to GUI discovery selection type (local or remote) private boolean local; /* *Update group GUI for adding/removing groups and *respective peers under groups. */ private void updateGUI (boolean stringCast, Enumeration enum) { String str = null; PeerGroupAdvertisement newAdv = null; MimeMediaType mmt = new MimeMediaType("text/xml"); SortedListModel groups = (SortedListModel)groupList.getModel(); while (enum.hasMoreElements()) { // Processing String objects if (stringCast) { str = (String)enum.nextElement(); try { // create an advertisement from each element newAdv = (PeerGroupAdvertisement) AdvertisementFactory.newAdvertisement (mmt, new ByteArrayInputStream(str.getBytes())); } catch (IOException ioe) { System.out.println ("Error parsing response element!"); ioe.printStackTrace(); continue; } } // Processing PeerGroupAdvertisement objects else { newAdv = (PeerGroupAdvertisement)enum.nextElement(); } System.out.println("Discovered group = " + newAdv.getName()); // found a new group, add them to the groupList if (groups.contains(newAdv.getName()) == false) { groups.addElement(newAdv.getName()); System.out.println("Discovered group = " + newAdv.getName() + " added"); } } // update the GUI groupList.setModel(groups); groupList.setSelectedValue(defaultGroupName, true); } /* *Start JXTA method. */ public void startJxta() { // flush local group cache flushGroupInfo(); } /* *Flush local group cache information. */ public void flushGroupInfo() { try { discovery.flushAdvertisements (null, DiscoveryService.GROUP); } catch (IOException e) { e.printStackTrace(); } } /* *On demand, discover groups locally or remotely *via a thread. */ public void run() { Enumeration enum = null; PeerGroupAdvertisement pga = null; SortedListModel groups = (SortedListModel)groupList.getModel(); try { //Add ourselves as a discoverylistener for //discovery response events. discovery.addDiscoveryListener(this); // check local cache for peer if (local) { enum = discovery.getLocalAdvertisements (DiscoveryService.GROUP, null, null); if (enum == null || enum.hasMoreElements() == false) { System.out.println ("No local advertisements found"); return; } System.out.println ("update GUI group discovery now"); // update group list in GUI updateGUI(false, enum); } // wait 10 seconds per remote discovery else { discovery.getRemoteAdvertisements (null, DiscoveryService.GROUP, null, null, 10, this); try { Thread.sleep(10 * 1000); } catch (Exception e) { } } } catch (Exception e) { e.printStackTrace(); } } /* *Handle remote discovery messages. */ public void discoveryEvent(DiscoveryEvent e) { DiscoveryResponseMsg drm = e.getResponse(); String response = drm.getPeerAdv(); InputStream is = null; MimeMediaType mmt = new MimeMediaType("text/xml"); try { //Create a group advertisement. is = new ByteArrayInputStream(response.getBytes()); peerAdv = (PeerAdvertisement) AdvertisementFactory.newAdvertisement(mmt, is); System.out.println("[ Received discovery response [" + drm.getResponseCount() +" elements] from group: " + peerAdv.getName() + " ]"); } catch (IOException ioe) { System.out.println("Error parsing remote peer's advertisement!"); ioe.printStackTrace(); return; } // update groups in GUI updateGUI(true, drm.getResponses()); } /* *Set discovery type *local = true > search is local *local = false > search is remote */ public void setLocalDiscovery(boolean local) { this.local = local; } /* *Creates new GroupDiscovery object. */ public GroupDiscovery(PeerGroup netPeerGroup, DiscoveryService discovery, JList groupList, String defaultGroupName) { this.netPeerGroup = netPeerGroup; this.discovery = discovery; this.groupList = groupList; this.defaultGroupName = defaultGroupName; local = true; } } Details of the SortedListModel ClassThe SortedListModel class is responsible for creating a tree of listmodel objects and storing them in a sorted set. It sorts the listmodel objects that are used to manage either peer or group lists. The SortedListModel class employs the following methods:
Listing 19.4 presents the code for SortedListModel.java. Listing 19.4 SortedListModel.java// Original source from : // // Copyright 1999 MageLang Institute // $Id //depot/main/src/edu/modules/Collections/magercises/Jlist /Solution/ SortedListModel.java#2 $ // // Source has been modified for JXTA dashboard. // import javax.swing.*; import java.util.*; public class SortedListModel extends AbstractListModel { // Define a SortedSet SortedSet model; public SortedListModel() { // Create a TreeSet // Store it in SortedSet variable model = new TreeSet(); } // ListModel methods public int getSize() { // Return the model size return model.size(); } public Object getElementAt(int index) { // Return the appropriate element return model.toArray()[index]; } // Other methods public void addElement(Object element) { if (model.add(element)) { fireContentsChanged(this, 0, getSize()); } } public void addAll(Object elements[]) { Collection c = Arrays.asList(elements); model.addAll(c); fireContentsChanged(this, 0, getSize()); } public void clear() { model.clear(); fireContentsChanged(this, 0, getSize()); } public boolean contains(Object element) { return model.contains(element); } public Enumeration elements() { // Return the appropriate element Vector v = new Vector(); int size = model.size(); for (int i = 0; i < size; i++) { v.addElement(model.toArray()[i]); } return v.elements(); } public Object firstElement() { // Return the appropriate element return model.first(); } public Iterator iterator() { return model.iterator(); } public Object lastElement() { // Return the appropriate element return model.last(); } public boolean removeElement(Object element) { boolean removed = model.remove(element); if (removed) { fireContentsChanged(this, 0, getSize()); } return removed; } } |