00001
00002
00003
00004
package org.nees.rbnb;
00005
00006
import javax.swing.JPanel;
00007
import javax.swing.JFrame;
00008
import javax.swing.JScrollPane;
00009
import javax.swing.JEditorPane;
00010
import javax.swing.JSplitPane;
00011
00012
import javax.swing.BorderFactory;
00013
00014
import javax.swing.JTree;
00015
import javax.swing.tree.DefaultMutableTreeNode;
00016
import javax.swing.tree.TreeSelectionModel;
00017
import javax.swing.tree.TreeModel;
00018
import javax.swing.tree.DefaultTreeModel;
00019
import javax.swing.event.TreeSelectionEvent;
00020
import javax.swing.event.TreeSelectionListener;
00021
00022
import javax.swing.Timer;
00023
00024
import java.awt.BorderLayout;
00025
import java.awt.Dimension;
00026
import java.awt.event.ActionEvent;
00027
import java.awt.event.ActionListener;
00028
00029
import java.util.Iterator;
00030
import java.util.List;
00031
import java.util.Vector;
00032
import java.util.Enumeration;
00033
import java.util.Date;
00034
import java.util.TimeZone;
00035
import java.text.SimpleDateFormat;
00036
00037
import com.rbnb.sapi.*;
00038
import com.rbnb.utility.ArgHandler;
00039
00040
00050 public class ChannelListSwing extends JPanel
00051 implements TreeSelectionListener
00052 {
00053
private static final String SERVER_NAME =
"localhost";
00054
private static final String SERVER_PORT =
"3333";
00055
00056
private static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat(
"MMM d, yyyy h:mm aa");
00057
private static final TimeZone TZ = TimeZone.getTimeZone(
"GMT");
00058
00059
private String server = SERVER_NAME +
":" + SERVER_PORT;
00060
00061
private Sink sink = null;
00062
private ChannelMap sMap;
00063
private boolean connected =
false;
00064
00065
private JTree tree;
00066
private JEditorPane htmlPane;
00067
private boolean needsRefresh =
false;
00068
private Timer checkRefresh;
00069
private Thread timerThread;
00070
private boolean runit =
false;
00071
00072
public static void main(String[] args) {
00073
00074
00075
final String[] a = args;
00076 javax.swing.SwingUtilities.invokeLater(
new Runnable() {
00077
public void run() {
00078
ChannelListSwing c =
new ChannelListSwing();
00079
if (c.setArgs(a))
00080 {
00081 c.connect();
00082 c.createAndShowGUI();
00083 c.setTimer();
00084 c.startCheckThread();
00085 }
00086 }
00087 });
00088 }
00089
00090
private void printUsage() {
00091 System.out.println(
"ChannelListSwing: usage is...");
00092 System.out.print(
"ChannelListSwing ");
00093 System.out.print(
"[-s Server Name *" + SERVER_NAME +
"] ");
00094 System.out.print(
"[-p Server Port *" + SERVER_PORT +
"] ");
00095 System.out.println();
00096 }
00097
00098
public boolean setArgs(String[] args) {
00099 String serverName = SERVER_NAME;
00100 String serverPort = SERVER_PORT;
00101
00102
try {
00103 ArgHandler ah=
new ArgHandler(args);
00104
if (ah.checkFlag(
'h')) {
00105 printUsage();
00106
return false;
00107 }
00108
if (ah.checkFlag(
's')) {
00109 String a=ah.getOption(
's');
00110
if (a!=null) serverName=a;
00111 }
00112
if (ah.checkFlag(
'p')) {
00113 String a=ah.getOption(
'p');
00114
if (a!=null) serverPort=a;
00115 }
00116 }
catch (Exception e) {
00117 System.err.println(
"ChannelList argument exception "+e.getMessage());
00118 e.printStackTrace();
00119
return false;
00120 }
00121
00122 setArgs(serverName,serverPort);
00123
00124 System.out.println(
"Starting ChannelList on " + server);
00125 System.out.println(
" Use ChannelList -h to see optional parameters");
00126
00127
return true;
00128 }
00129
00130
public ChannelListSwing()
00131 {
00132 setArgs(SERVER_NAME,SERVER_PORT);
00133 }
00134
00135
public void setArgs(String serverName, String serverPort)
00136 {
00137 server = serverName +
":" + serverPort;
00138 }
00139
00140
protected void createAndShowGUI() {
00141
00142
00143
00144
00145
00146 JFrame frame =
new JFrame(
"Channel List");
00147
00148
00149 initGraphics();
00150 setOpaque(
true);
00151 frame.setContentPane(
this);
00152
00153
00154 frame.pack();
00155 frame.setVisible(
true);
00156 }
00157
00158
protected void initGraphics() {
00159 setLayout(
new BorderLayout());
00160 setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
00161
00162
00163 DefaultMutableTreeNode top = createNodes();
00164
00165
00166 tree =
new JTree(top);
00167 tree.getSelectionModel().setSelectionMode
00168 (TreeSelectionModel.SINGLE_TREE_SELECTION);
00169
00170
00171 tree.addTreeSelectionListener(
this);
00172
00173
00174 JScrollPane treeView =
new JScrollPane(tree);
00175
00176
00177 htmlPane =
new JEditorPane();
00178 htmlPane.setEditable(
false);
00179 JScrollPane htmlView =
new JScrollPane(htmlPane);
00180
00181
00182 JSplitPane splitPane =
new JSplitPane(JSplitPane.VERTICAL_SPLIT);
00183 splitPane.setTopComponent(treeView);
00184 splitPane.setBottomComponent(htmlView);
00185
00186 Dimension minimumSize =
new Dimension(100, 50);
00187 htmlView.setMinimumSize(minimumSize);
00188 treeView.setMinimumSize(minimumSize);
00189 splitPane.setDividerLocation(100);
00190
00191
00192
00193
00194 splitPane.setPreferredSize(
new Dimension(500, 300));
00195
00196
00197 add(splitPane);
00198
00199
00200 JFrame itsFrame =
new JFrame(
"ChannelList");
00201 itsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
00202 itsFrame.setSize(
new Dimension(120, 40));
00203 itsFrame.getContentPane().add(
this, BorderLayout.CENTER);
00204
00205
00206 itsFrame.pack();
00207 itsFrame.setVisible(
true);
00208 }
00209
00210
protected void setTimer()
00211 {
00212
int delay = 100;
00213 ActionListener taskPerformer =
new ActionListener() {
00214
public void actionPerformed(ActionEvent evt) {
00215
if (needsRefresh)
00216 {
00217
00218 DefaultMutableTreeNode top = createNodes();
00219 DefaultTreeModel model =
new DefaultTreeModel(top);
00220 tree.setModel(model);
00221 invalidate();
00222 needsRefresh =
false;
00223 }
00224 }
00225 };
00226 checkRefresh =
new Timer(delay, taskPerformer);
00227 checkRefresh.start();
00228 }
00229
00230
00231
private DefaultMutableTreeNode createNodes() {
00232 DefaultMutableTreeNode top;
00233
if (!connected)
00234 top =
new DefaultMutableTreeNode(
"UNCONNECTED (attempting to connect to "
00235 + server +
")");
00236
else
00237 {
00238 top =
new DefaultMutableTreeNode(
"Connected to " + server);
00239 ChannelTree ct = getChannelTree();
00240
if (ct == null)
00241 {
00242 top =
new DefaultMutableTreeNode(
"No Channel Tree (connection dropped?)");
00243 }
00244
else
00245 {
00246 Iterator i = ct.rootIterator();
00247
while (i.hasNext())
00248 {
00249 top.add(makeNodes((ChannelTree.Node)i.next()));
00250 }
00251 }
00252 }
00253
00254
return top;
00255 }
00256
00257
private DefaultMutableTreeNode makeNodes(ChannelTree.Node node)
00258 {
00259 DefaultMutableTreeNode root =
new DefaultMutableTreeNode(
new NodeCover(node));
00260 List l = node.getChildren();
00261 Iterator i = l.iterator();
00262
while (i.hasNext())
00263 {
00264 root.add(makeNodes((ChannelTree.Node)i.next()));
00265 }
00266
00267
return root;
00268 }
00269
00271 public void valueChanged(TreeSelectionEvent e) {
00272 DefaultMutableTreeNode node = (DefaultMutableTreeNode)
00273 tree.getLastSelectedPathComponent();
00274
00275
if (node == null)
return;
00276 Object nodeInfo = node.getUserObject();
00277
if (nodeInfo instanceof NodeCover)
00278 {
00279 NodeCover nc = (NodeCover)nodeInfo;
00280 ChannelTree.Node ctNode = nc.node;
00281 displayMetaData(ctNode);
00282 }
00283
else
00284 {
00285 htmlPane.setText(nodeInfo.toString());
00286 }
00287 }
00288
00289
protected void connect()
00290 {
00291
try {
00292
00293 sink=
new Sink();
00294 sink.OpenRBNBConnection(server,
"ChannelListRequest");
00295 connected =
true;
00296 System.out.println(
"ChannelList: Connection made to server = "
00297 + server +
" requesting channel list.");
00298 }
00299
catch (SAPIException se)
00300 {
00301 System.out.println(
"ChannelList: Cannot connect to "
00302 + server +
"; exception = " + se);
00303 }
00304 }
00305
00306
private ChannelTree getChannelTree() {
00307
try {
00308 sMap =
new ChannelMap();
00309 sink.RequestRegistration();
00310 sMap = sink.Fetch(-1,sMap);
00311
return ChannelTree.createFromChannelMap(sMap);
00312 }
00313
catch (SAPIException se)
00314 {
00315 System.out.println(
"ChannelList: get channel tree failed. Reconnect?");
00316 System.out.println(
"Exception = " + se);
00317 connected =
false;
00318 }
00319
return null;
00320 }
00321
00322
private void displayMetaData(ChannelTree.Node node) {
00323
double start = node.getStart();
00324
double duration = node.getDuration();
00325
double end = start + duration;
00326
00327
long unixTime = (
long)(start * 1000.0);
00328 String startTime = DATE_FORMAT.format(
new Date(unixTime));
00329 unixTime = (
long)(end * 1000.0);
00330 String endTime = DATE_FORMAT.format(
new Date(unixTime));
00331
00332
if (((node.getType()).toString()).equals(
"Channel"))
00333 htmlPane.setText(
00334
"FullName = " + node.getFullName() +
"\n" +
00335
"Time (start, duration) = " + start +
", " + duration +
"\n" +
00336
"[Assuming \"standard\" time:" +
"\n" +
00337
" from " + startTime +
"\n" +
00338
" to " + endTime +
"]\n" +
00339
"Type = " + node.getType() +
"\n" +
00340
"Mime type = " + node.getMime() +
"\n" +
00341
"Size = " + node.getSize()
00342 );
00343
else
00344 htmlPane.setText(
00345
"FullName = " + node.getFullName() +
"\n" +
00346
"Type = " + node.getType() +
"\n"
00347 );
00348 }
00349
00350
protected void startCheckThread()
00351 {
00352
00353 Runnable r =
new Runnable() {
00354
public void run() {
00355 runWork();
00356 }
00357 };
00358 runit =
true;
00359 timerThread =
new Thread(r,
"Timer");
00360 timerThread.start();
00361 System.out.println(
"Started checker thread.");
00362 }
00363
00364
private void stopThread()
00365 {
00366 runit =
false;
00367 timerThread.interrupt();
00368 System.out.println(
"Stopped checker thread.");
00369 }
00370
00371
private void runWork ()
00372 {
00373
int delay = 10000;
00374
while(runit)
00375 {
00376
if (!connected)
00377 {
00378 delay = 10000;
00379
00380 connect();
00381
if (connected) delay = 1000;
00382 }
00383
else if (!sameTree(tree))
00384 {
00385 System.out.println(
"Found mismatched tree");
00386 needsRefresh =
true;
00387 }
00388
try {Thread.sleep(delay);}
catch (InterruptedException ignore) {}
00389 }
00390 timerThread = null;
00391 }
00392
00393
private boolean sameTree(JTree tree)
00394 {
00395 TreeModel m = tree.getModel();
00396 ChannelTree ct = getChannelTree();
00397
if (ct == null)
return false;
00398
return sameTreeNodes(ct.rootIterator(),(DefaultMutableTreeNode)m.getRoot());
00399 }
00400
00401
private boolean sameTreeNodes(Iterator i, DefaultMutableTreeNode tree)
00402 {
00403
00404
00405
00406
00407
00408
00409
if (tree.isLeaf() && !i.hasNext())
00410 {
00411
00412
return true;
00413 }
00414
00415
if (tree.isLeaf() && i.hasNext())
00416 {
00417
00418
return false;
00419 }
00420
00421
if (!tree.isLeaf() && !i.hasNext())
00422 {
00423
00424
return false;
00425 }
00426
00427
00428
00429
00430 Vector nodeList =
new Vector();
00431
int count = tree.getChildCount();
00432
for (
int k = 0; k < count; k++)
00433 {
00434 nodeList.add(tree.getChildAt(k));
00435 }
00436
00437
while (i.hasNext())
00438 {
00439 ChannelTree.Node n = (ChannelTree.Node)i.next();
00440 Enumeration e = nodeList.elements();
00441 DefaultMutableTreeNode found = null;
00442
while(e.hasMoreElements())
00443 {
00444 DefaultMutableTreeNode test = (DefaultMutableTreeNode)e.nextElement();
00445 Object nodeInfo = test.getUserObject();
00446 NodeCover nc = (NodeCover)nodeInfo;
00447 ChannelTree.Node ctNode = nc.node;
00448
if (n.getName().equals(ctNode.getName()))
00449 {
00450 found = test;
00451
break;
00452 }
00453 }
00454
if (found == null)
return false;
00455 nodeList.remove(found);
00456
if (!sameTreeNodes(n.getChildren().iterator(),found))
return false;
00457 }
00458
if (nodeList.size() > 0)
00459 {
00460
00461
return false;
00462 }
00463
return true;
00464 }
00465
00466
private class NodeCover
00467 {
00468 ChannelTree.Node node;
00469
00470 NodeCover(ChannelTree.Node node)
00471 {
00472
this.node = node;
00473 }
00474
00475
public String toString()
00476 {
00477
return node.getName();
00478 }
00479 }
00480 }