Commit 52dfb53d authored by David Johnson's avatar David Johnson

This commit contains several things:

  * the google maps interface to the applet
  * a new control panel
  * a cache for dynamic web content that evicts if memory runs low
  * (some) comment cleanup
  * updated copyrights
parent b79d0dcc
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
public class CollapsablePanel extends javax.swing.JPanel {
String title;
public CollapsablePanel() {
initComponents();
}
public CollapsablePanel(String title) {
this.title = title;
initComponents();
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return this.title;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.GridBagLayout());
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class CollapsablePanelContainer extends javax.swing.JPanel {
// title :: panel
Hashtable childPanels;
// title :: GridBagConstraints
Hashtable childConstraints;
// title :: state (false == uncollapsed)
Hashtable childPanelState;
// title :: int (index)
Hashtable childPanelIndex;
// title :: JButton
Hashtable childPanelButtons;
public CollapsablePanelContainer() {
childPanels = new Hashtable();
childConstraints = new Hashtable();
childPanelState = new Hashtable();
childPanelIndex = new Hashtable();
childPanelButtons = new Hashtable();
initComponents();
this.removeAll();
}
public void add(JComponent c,Object la) {
if (c instanceof CollapsablePanel) {
appendChildPanel(((CollapsablePanel)c).getTitle(),c,la);
}
else {
appendChildPanel("unk",c,la);
}
}
void appendChildPanel(String title,JComponent ccp,Object layoutArg) {
Set cpNames = childPanels.keySet();
if (cpNames == null || cpNames.contains(title)) {
return;
}
int y = childPanels.size() * 2;
childPanelIndex.put(title,new Integer(y));
childPanels.put(title,ccp);
childPanelState.put(title,new Boolean(false));
GridBagConstraints gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.NORTHWEST;
gc.gridx = 0;
gc.gridy = y;
//gc.weighty = 1.0;
JButton ocButton = new javax.swing.JButton();
//ocButton.setFont(new java.awt.Font("Dialog", 1, 10));
ocButton.setIcon(new ImageIcon(getClass().getResource("/open.gif")));
ocButton.setBorderPainted(false);
ocButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
childPanelButtons.put(title,ocButton);
final CollapsablePanelContainer cpc = this;
final String lTitle = title;
ocButton.addActionListener(new ActionListener() {
final String myTitle = lTitle;
final CollapsablePanelContainer myCPC = cpc;
public void actionPerformed(ActionEvent evt) {
myCPC.invertState(myTitle);
}
});
super.add(ocButton,gc);
gc.gridx = 1;
gc.anchor = GridBagConstraints.NORTHWEST;
//gc.weightx = 1.0;
JLabel ocLabel = new JLabel(title);
ocLabel.setFont(new java.awt.Font("Dialog", 1, 12));
super.add(ocLabel,gc);
// Border pBorder = BorderFactory.createTitledBorder(null,"",
// javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
// javax.swing.border.TitledBorder.DEFAULT_POSITION,
// new java.awt.Font("Dialog", 0, 10));
Border pBorder = BorderFactory.createLineBorder(Color.GRAY,1);
ccp.setBorder(pBorder);
gc.anchor = GridBagConstraints.NORTHWEST;
gc.gridy = y + 1;
gc.gridx = 0;
gc.gridwidth = 2;
if (layoutArg instanceof GridBagConstraints) {
GridBagConstraints igc = (GridBagConstraints)layoutArg;
// just need to set the grid args; leave the rest intact.
//igc.anchor = GridBagConstraints.NORTHWEST;
//igc.fill = GridBagConstraints.BOTH;
//igc.weightx = 1.0;
//igc.weighty = 1.0;
igc.gridy = y + 1;
igc.gridx = 0;
igc.gridwidth = 2;
this.childConstraints.put(title,igc);
super.add(ccp,igc);
}
else {
this.childConstraints.put(title,gc);
super.add(ccp,gc);
}
this.revalidate();
this.repaint();
}
public void invertState(String title) {
Boolean pstate = (Boolean)childPanelState.get(title);
if (pstate == null) {
return;
}
setCollapsed(title,!pstate.booleanValue());
}
public void setCollapsed(String title,boolean collapsed) {
Boolean pstate = (Boolean)childPanelState.get(title);
if (pstate == null || pstate.booleanValue() == collapsed) {
return;
}
else {
childPanelState.put(title,new Boolean(collapsed));
if (collapsed) {
JComponent oc = (JComponent)childPanels.get(title);
super.remove(oc);
JButton ocButton = (JButton)childPanelButtons.get(title);
ocButton.setIcon(new ImageIcon(getClass().getResource("/closed.gif")));
this.revalidate();
this.repaint();
}
else {
int y = ((Integer)childPanelIndex.get(title)).intValue();
GridBagConstraints gc = (GridBagConstraints)childConstraints.get(title);
// gc.anchor = GridBagConstraints.NORTHWEST;
// gc.gridx = 0;
// gc.gridy = y + 1;
// gc.gridwidth = 2;
super.add((Component)childPanels.get(title),gc);
JButton ocButton = (JButton)childPanelButtons.get(title);
ocButton.setIcon(new ImageIcon(getClass().getResource("/open.gif")));
this.revalidate();
this.repaint();
}
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
jButton1 = new javax.swing.JButton();
setLayout(new java.awt.GridBagLayout());
jButton1.setFont(new java.awt.Font("Dialog", 1, 10));
jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/open.gif")));
jButton1.setText("jButton1");
add(jButton1, new java.awt.GridBagConstraints());
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
// End of variables declaration//GEN-END:variables
}
This diff is collapsed.
This diff is collapsed.
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005-2006 University of Utah and the Flux Group.
* All rights reserved.
*/
public class DataCacheEvent {
private DataCache src;
private DataCacheObject obj;
private Exception exception;
public DataCacheEvent(DataCache cache,DataCacheObject o) {
this.src = cache;
this.obj = o;
this.exception = null;
}
void setException(Exception ex) {
this.exception = ex;
}
public DataCache getSource() {
return this.src;
}
public DataCacheObject getCacheObject() {
return this.obj;
}
public Exception getException() {
return this.exception;
}
public boolean isSuccess() {
return (this.exception == null)?true:false;
}
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
public interface DataCacheListener {
public void dataRetrieved(DataCacheEvent evt);
public void dataRetrievalFailure(DataCacheEvent evt);
public void dataEvicted(DataCacheEvent evt);
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
import java.net.URL;
/*
* Wraps a data object so that the user never has to keep a reference
* to the object. This is necessary so that the cache can remove objects
* from memory... and it will only work if the user NEVER keeps a reference
* to a cached object --- they use it and discard their ref.
*/
class DataCacheObject {
private URL url;
private DataCache cache;
private int evictPolicy;
public DataCacheObject(DataCache cache,URL u,int evictPolicy) {
this.cache = cache;
this.url = u;
this.evictPolicy = evictPolicy;
}
public URL getURL() {
return url;
}
public DataCache getCache() {
return cache;
}
public int getEvictPolicy() {
return this.evictPolicy;
}
/*
* This method blocks until the cache delivers the object; returns
* null if the cache could not deliver (i.e., OutOfMemory).
*/
public Object getObject() {
return this.cache.getURL(this);
}
/*
* Here, we basically trigger off a "fetch" request; the idea is that
* a call to getObjectAsync can be followed directly with a call to
* getObject. We can't return the object in the listener event,
* because that would violate the cache policy of never letting anybody
* but the user directly use the cached object. Thus, we accept the
* slight race. Quite frankly, there won't be much of a race if
* the user has setup their listener correctly---they will get a
* dataEvicted message before they call getObject.
*
* A little hysteresis reduces the probability of this race, since we
* keep objects around for at least 10s before evicting them (LRU also
* minimizes the odds).
*/
public void getObjectAsync() {
this.cache.preloadURL(this);
}
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* Dataset.java
*
* Created on July 7, 2006, 2:53 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.util.*;
/**
*
* @author david
*/
public class Dataset {
public String name;
public String building;
......@@ -31,6 +18,7 @@ public class Dataset {
public String dataFile;
public MapDataModel model;
// "<floor>-<scale>" :: DataCacheObject
public Hashtable bgImages;
public GenericWirelessData data;
public NodePosition positions;
......@@ -72,15 +60,15 @@ public class Dataset {
// buildings. For me, one building per dataset is good enough for our
// needs into the foreseeable future... just like 64k. :-)
public java.awt.Image getImage(int floor,int scale) {
System.err.println("getting image for building="+this.building+",floor="+floor+",scale="+scale);
System.err.println("getting cache image for building="+this.building+",floor="+floor+",scale="+scale);
String tag = "" + floor + "-" + scale;
return (java.awt.Image)this.bgImages.get(tag);
return (java.awt.Image)((DataCacheObject)this.bgImages.get(tag)).getObject();
}
public void addImage(java.awt.Image img,int floor,int scale) {
System.err.println("adding image for building="+this.building+",floor="+floor+",scale="+scale);
public void addImage(DataCacheObject dco,int floor,int scale) {
System.err.println("adding cache image for building="+this.building+",floor="+floor+",scale="+scale);
String tag = "" + floor + "-" + scale;
this.bgImages.put(tag,img);
this.bgImages.put(tag,dco);
}
public float getScaleFactor(int scale) {
......@@ -136,4 +124,20 @@ public class Dataset {
}
}
public int[] getScales() {
return this.scale;
}
public boolean isScale(int f) {
if (this.scale == null) {
return false;
}
for (int i = 0; i < this.scale.length; ++i) {
if (this.scale[i] == f) {
return true;
}
}
return false;
}
}
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* GenericLinkStats.java
*
* Created on July 4, 2006, 11:08 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.util.*;
/**
*
* @author david
*/
public class GenericLinkStats {
private GenericStats gs;
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* GenericStats.java
*
* Created on July 3, 2006, 8:37 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.util.*;
import java.io.*;
import java.util.regex.*;
/**
*
* @author david
*/
public class GenericStats implements GenericWirelessData {
Hashtable indexMapping;
......@@ -31,7 +18,6 @@ public class GenericStats implements GenericWirelessData {
Hashtable maxPropValues;
Hashtable indexValues;
/** Creates a new instance of GenericStats */
protected GenericStats(String[] indices,Hashtable indexValues,
Vector nodes,Vector properties,
Hashtable minPropValues,Hashtable maxPropValues,
......@@ -88,12 +74,12 @@ public class GenericStats implements GenericWirelessData {
}
}
System.out.println("trying dsString='"+dsString+"'");
//System.out.println("trying dsString='"+dsString+"'");
Dataset ds = (Dataset)this.indexMapping.get(dsString);
if (ds != null) {
GenericLinkStats[] retval = ds.getAllStats();
System.out.println("allstats.length = " + retval.length);
//System.out.println("allstats.length = " + retval.length);
return retval;
}
return null;
......@@ -533,7 +519,7 @@ public class GenericStats implements GenericWirelessData {
gls.addStat(statName,obj);
}
else {
System.out.println("line " + linecount + ": bad data line!");
System.err.println("line " + linecount + ": bad data line!");
}
}
}
......@@ -551,7 +537,7 @@ public class GenericStats implements GenericWirelessData {
throw new IOException("file read failed");
}
System.err.println("GenericStats parsed "+linecount+" lines.");
System.out.println("GenericStats parsed "+linecount+" lines.");
GenericStats retval = new GenericStats(indices,indexValues,
nodes,properties,
......@@ -645,7 +631,7 @@ public class GenericStats implements GenericWirelessData {
}
public GenericLinkStats[] getAllStats() {
System.out.println("real allStats.size in ds ="+allStats.size());
//System.out.println("real allStats.size in ds ="+allStats.size());
GenericLinkStats[] retval = new GenericLinkStats[allStats.size()];
int i = 0;
for (Enumeration e1 = allStats.elements(); e1.hasMoreElements(); ) {
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* GenericWirelessData.java
*
* Created on July 6, 2006, 7:45 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.util.*;
/**
*
* @author david
*/
public interface GenericWirelessData {
public String[] getNodes();
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005-2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005-2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -65,4 +65,4 @@ public class LinkStats {
public float getStddevRSSI() {
return stddevRSSI;
}
}
}
\ No newline at end of file
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005-2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* LinkWidget.java
*
* Created on July 11, 2005, 8:24 AM
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
import java.awt.*;
import java.awt.geom.*;
/**
*
* @author david
*/
public class LinkWidget extends Widget {
private int x1,y1;
......@@ -316,7 +302,7 @@ public class LinkWidget extends Widget {
retvals[1] += ticks;
}
System.out.println("getLinkColor returning {"+retvals[0]+","+retvals[1]+","+retvals[2]+"}; percent was "+percent);
//System.out.println("getLinkColor returning {"+retvals[0]+","+retvals[1]+","+retvals[2]+"}; percent was "+percent);
return retvals;
}
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2006 University of Utah and the Flux Group.
* Copyright (c) 2006-2007 University of Utah and the Flux Group.
* All rights reserved.
*/