You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@excalibur.apache.org by le...@apache.org on 2004/07/27 19:37:37 UTC

svn commit: rev 30791 - in excalibur/trunk/containerkit/instrument-client: . src/java/org/apache/excalibur/instrument/client src/java/org/apache/excalibur/instrument/client/http

Author: leif
Date: Tue Jul 27 10:37:36 2004
New Revision: 30791

Added:
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Data.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ElementData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleElementData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleSnapshotData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleUtils.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentableData.java
Modified:
   excalibur/trunk/containerkit/instrument-client/   (props changed)
   excalibur/trunk/containerkit/instrument-client/maven.xml
   excalibur/trunk/containerkit/instrument-client/project.xml
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/AbstractInternalFrame.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ConnectDialog.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/CreateSampleDialog.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentClientFrame.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerTreeModel.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentNodeData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleNodeData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableNodeData.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Main.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MaintainedSampleLease.java
   excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MenuBar.java
Log:
Major rewrite to move from AltRMI to HTTP as the transport for communicating with the server.

Modified: excalibur/trunk/containerkit/instrument-client/maven.xml
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/maven.xml	(original)
+++ excalibur/trunk/containerkit/instrument-client/maven.xml	Tue Jul 27 10:37:36 2004
@@ -1,9 +1,36 @@
-<project default="site" xmlns:maven="jelly:maven" xmlns:j="jelly:core" xmlns:util="jelly:util"
+<project default="dev" xmlns:maven="jelly:maven" xmlns:j="jelly:core" xmlns:util="jelly:util"
         xmlns:deploy="deploy">
 
     <property file="${basedir}/../project.properties"/>
     <property file="${basedir}/project.properties"/>
 
+    <goal name="dev"
+        prereqs="jar"
+        description="Creates a dev directory containing a build for development testing.">
+        
+        <mkdir dir="${basedir}/dev"/>
+
+        <!-- bin directory -->
+        <mkdir dir="${basedir}/dev/bin"/>
+        <copy todir="${basedir}/dev/bin">
+            <fileset dir="${maven.src.dir}/bin">
+                <include name="*"/>
+            </fileset>
+        </copy>
+        
+        <!-- lib directory -->
+        <mkdir dir="${basedir}/dev/lib"/>
+        <deploy:copy-deps todir="${basedir}/dev/lib"/>
+        <copy todir="${basedir}/dev/lib">
+          <fileset dir="${maven.build.dir}">
+            <include name="${maven.final.name}.jar"/>
+          </fileset>
+        </copy>
+        
+        <!-- conf directory -->
+        <mkdir dir="${basedir}/dev/conf"/>
+    </goal>
+    
     <postGoal name="dist:prepare-bin-filesystem">
         <mkdir dir="${maven.dist.bin.assembly.dir}/bin"/>
 
@@ -12,44 +39,18 @@
                 <include name="*"/>
             </fileset>
         </copy>
-
+        
         <mkdir dir="${maven.dist.bin.assembly.dir}/lib"/>
 
         <deploy:copy-deps todir="${maven.dist.bin.assembly.dir}/lib"/>
+        
+        <!-- The dist:prepare-bin-filesystem goal puts the client jar in the
+            root directory, but we want it in the lib directory. -->
+        <copy todir="${maven.dist.bin.assembly.dir}/lib">
+          <fileset dir="${maven.build.dir}">
+            <include name="${maven.final.name}.jar"/>
+          </fileset>
+        </copy>
+        <delete file="${maven.dist.bin.assembly.dir}/${maven.final.name}.jar"/>
     </postGoal>
-
-    <postGoal name="java:compile">
-        <attainGoal name="altrmiproxies"/>
-    </postGoal>
-
-    <goal name="altrmiproxies">
-        <taskdef name="altrmiproxies"
-                classname="org.apache.altrmi.generator.ant.ProxyGenerationTask">
-            <classpath>
-                <path refid="maven.dependency.classpath"/>
-                <pathelement path="${maven.build.dir}/classes"/>
-            </classpath>
-        </taskdef>
-
-        <mkdir dir="${maven.build.dir}/genjava"/>
-        <mkdir dir="${maven.build.dir}/classes"/>
-
-        <delete>
-            <fileset dir="${maven.build.dir}/genjava" includes="AltrmiGenerated*.java"/>
-        </delete>
-        <delete>
-            <fileset dir="${maven.build.dir}/classes" includes="AltrmiGenerated*.class"/>
-        </delete>
-
-        <altrmiproxies genname="InstrumentManagerClient"
-            srcgendir="${maven.build.dir}/genjava"
-            classgendir="${maven.build.dir}/classes"
-            interfaces="org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient"
-            additionalfacades="org.apache.excalibur.instrument.manager.interfaces.InstrumentableDescriptor,org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor,org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleDescriptor">
-            <classpath>
-                <path refid="maven.dependency.classpath"/>
-                <pathelement path="${maven.build.dir}/classes"/>
-            </classpath>
-        </altrmiproxies>
-    </goal>
 </project>

Modified: excalibur/trunk/containerkit/instrument-client/project.xml
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/project.xml	(original)
+++ excalibur/trunk/containerkit/instrument-client/project.xml	Tue Jul 27 10:37:36 2004
@@ -38,54 +38,5 @@
             <id>avalon-framework</id>
             <version>4.1.4</version>
         </dependency>
-        <dependency>
-            <id>altrmi-common</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
-        <dependency>
-            <id>altrmi-client-interfaces</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
-        <dependency>
-            <id>altrmi-client-impl</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
-        <dependency>
-            <id>altrmi-generator</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
-        <dependency>
-            <groupId>excalibur-instrument</groupId>
-            <artifactId>excalibur-instrument</artifactId>
-            <version>1.2</version>
-        </dependency>
-        <dependency>
-            <groupId>excalibur-instrument</groupId>
-            <artifactId>excalibur-instrument-spi</artifactId>
-            <version>1.2</version>
-        </dependency>
-        <dependency>
-            <groupId>excalibur-instrument</groupId>
-            <artifactId>excalibur-instrument-impl</artifactId>
-            <version>1.2</version>
-        </dependency>
-
-        <dependency>
-            <!-- generation task only -->
-            <id>altrmi-server-interfaces</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
-        <dependency>
-            <!-- generation task only -->
-            <id>altrmi-server-impl</id>
-            <version>0.9.6</version>
-            <groupId>altrmi</groupId>
-        </dependency>
     </dependencies>
-
 </project>

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/AbstractInternalFrame.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/AbstractInternalFrame.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/AbstractInternalFrame.java	Tue Jul 27 10:37:36 2004
@@ -28,6 +28,9 @@
 
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
 
 /**
  *
@@ -37,9 +40,11 @@
  */
 abstract class AbstractInternalFrame
     extends JInternalFrame
-    implements InternalFrameListener
+    implements InternalFrameListener, LogEnabled
 {
     private InstrumentClientFrame m_frame;
+    private Logger m_logger;
+    
     private JInternalFrame m_nextFrame;
     private boolean m_loaded;
     private boolean m_active;
@@ -112,10 +117,33 @@
 
         m_loaded = false;
     }
+    
+    /*---------------------------------------------------------------
+     * LogEnabled Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Sets the Logger to be used by the component.
+     *
+     * @param logger The Logger.
+     */
+    public void enableLogging( Logger logger )
+    {
+        m_logger = logger;
+    }
 
     /*---------------------------------------------------------------
      * Methods
      *-------------------------------------------------------------*/
+    /**
+     * Returns the logger to be used by the component.
+     *
+     * @return The Logger.
+     */
+    protected Logger getLogger()
+    {
+        return m_logger;
+    }
+    
     /**
      * Adds the frame to the desktop in a simple and dumb cascading format.
      */

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ConnectDialog.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ConnectDialog.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ConnectDialog.java	Tue Jul 27 10:37:36 2004
@@ -18,6 +18,8 @@
 package org.apache.excalibur.instrument.client;
 
 import java.awt.Component;
+import java.net.MalformedURLException;
+import java.net.URL;
 
 import javax.swing.JOptionPane;
 import javax.swing.JTextField;
@@ -31,10 +33,8 @@
 class ConnectDialog
     extends AbstractTabularOptionDialog
 {
-    private JTextField m_hostField;
-    private String m_host;
-    private JTextField m_portField;
-    private int m_port;
+    private JTextField m_urlField;
+    private URL m_url;
     
     /*---------------------------------------------------------------
      * Constructors
@@ -60,7 +60,7 @@
      */
     protected String getMessage()
     {
-        return "Please enter the host and port of the InstrumentManager to connect to.";
+        return "Please enter the url of the InstrumentManager to connect to.";
     }
     
     /**
@@ -70,38 +70,19 @@
      */
     protected boolean validateFields()
     {
-        // Check the host.
-        String host = m_hostField.getText().trim();
-        if ( host.length() == 0 )
-        {
-            JOptionPane.showMessageDialog( this, "Please enter a valid host name or IP address.",
-                "Invalid host", JOptionPane.ERROR_MESSAGE );
-            return false;
-        }
-        m_host = host;
-        
-        // Check the port.
-        boolean portOk = true;
-        int port = 0;
+        // Check the URL.
+        URL url;
         try
         {
-            port = Integer.parseInt( m_portField.getText().trim() );
-        }
-        catch ( NumberFormatException e )
-        {
-            portOk = false;
-        }
-        if ( ( port < 0 ) || ( port > 65535 ) )
-        {
-            portOk = false;
+            url = new URL( m_urlField.getText().trim() );
         }
-        if ( !portOk )
+        catch ( MalformedURLException e )
         {
-            JOptionPane.showMessageDialog( this, "Please enter a valid port. (1-65535)",
-                "Invalid port", JOptionPane.ERROR_MESSAGE );
+            JOptionPane.showMessageDialog( this, "Please enter a valid url: " + e.getMessage(),
+                "Invalid URL", JOptionPane.ERROR_MESSAGE );
             return false;
         }
-        m_port = port;
+        m_url = url;
         
         return true;
     }
@@ -119,8 +100,7 @@
     {
         return new String[]
         {
-            "Host:",
-            "Port:"
+            "URL:"
         };
     }
     
@@ -131,15 +111,12 @@
      */
     protected Component[] getMainPanelComponents()
     {
-        m_hostField = new JTextField();
-        m_hostField.setColumns( 20 );
-        m_portField = new JTextField();
-        m_portField.setColumns( 6 );
+        m_urlField = new JTextField();
+        m_urlField.setColumns( 30 );
         
         return new Component[]
         {
-            m_hostField,
-            m_portField
+            m_urlField
         };
     }
         
@@ -147,45 +124,24 @@
      * Methods
      *-------------------------------------------------------------*/
     /**
-     * Sets the initial host to be shown in the host TextField.
-     *
-     * @param host The initial host.
-     */
-    void setHost( String host )
-    {
-        m_host = host;
-        m_hostField.setText( host );
-    }
-    
-    /**
-     * Returns the host set in the dialog.
-     *
-     * @return The host.
-     */
-    String getHost()
-    {
-        return m_host;
-    }
-    
-    /**
-     * Sets the initial port to be shown in the port TextField.
+     * Sets the initial URL to be shown in the URL TextField.
      *
-     * @param port The initial port.
+     * @param url The initial URL.
      */
-    void setPort( int port )
+    void setURL( URL url )
     {
-        m_port = port;
-        m_portField.setText( Integer.toString( port ) );
+        m_url = url;
+        m_urlField.setText( url.toExternalForm() );
     }
     
     /**
-     * Returns the port set in the dialog.
+     * Returns the URL set in the dialog.
      *
-     * @return The port.
+     * @return The URL.
      */
-    int getPort()
+    URL getURL()
     {
-        return m_port;
+        return m_url;
     }
 }
 

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/CreateSampleDialog.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/CreateSampleDialog.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/CreateSampleDialog.java	Tue Jul 27 10:37:36 2004
@@ -17,18 +17,25 @@
 
 package org.apache.excalibur.instrument.client;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
+import java.awt.event.ActionEvent;
 
+import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.Box;
 import javax.swing.ButtonGroup;
+import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JOptionPane;
 import javax.swing.JRadioButton;
 import javax.swing.JTextField;
-
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
 
 /**
  *
@@ -39,11 +46,16 @@
 class CreateSampleDialog
     extends AbstractTabularOptionDialog
 {
-    private InstrumentDescriptor m_instrumentDescriptor;
+    private int m_instrumentType;
     private JTextField m_instrumentNameField;
     private JTextField m_instrumentDescriptionField;
     private JTextField m_sampleDescriptionField;
     private String m_sampleDescription;
+    
+    /** Remembers the last default description so we can tell whether or not the
+     *   user has modified the description manually. */
+    private String m_lastDefaultDescription;
+    
     private JTextField m_intervalField;
     private long m_interval;
     private JTextField m_sizeField;
@@ -66,17 +78,34 @@
      * Creates a new CreateSampleDialog.
      *
      * @param frame Frame which owns the dialog.
-     */
-    CreateSampleDialog( InstrumentClientFrame frame, InstrumentDescriptor instrumentDescriptor )
+     * @param name Name of the instrument.
+     * @param description Description of the instrument.
+     * @param type Type of the instrument.
+     */
+    CreateSampleDialog( InstrumentClientFrame frame,
+                        String name,
+                        String description,
+                        int type )
     {
         super( frame, "Create Instrument Sample",
             AbstractOptionDialog.BUTTON_OK | AbstractOptionDialog.BUTTON_CANCEL );
         
-        m_instrumentDescriptor = instrumentDescriptor;
-        m_instrumentNameField.setText( m_instrumentDescriptor.getName() );
-        m_instrumentDescriptionField.setText( m_instrumentDescriptor.getDescription() );
+        m_instrumentType = type;
+        m_instrumentNameField.setText( name );
+        m_instrumentDescriptionField.setText( description );
         
         buildSampleTypeComponent();
+
+        // Set the default values.
+        setInterval( 1000 );
+        setSampleCount( 600 );  // 10 minutes of history
+        setLeaseTime( 600 );
+        setMaintainLease( true );
+        
+        m_lastDefaultDescription =
+            InstrumentSampleUtils.getDefaultDescriptionForType( m_sampleType, m_interval );
+        setSampleDescription( m_lastDefaultDescription );
+        
         pack();
     }
     
@@ -95,116 +124,12 @@
     
     /**
      * Goes through and validates the fields in the dialog.
-     *
+     * 
      * @return True if the fields were Ok.
      */
     protected boolean validateFields()
     {
-        // Check the description.
-        String description = m_sampleDescriptionField.getText().trim();
-        if ( description.length() == 0 )
-        {
-            JOptionPane.showMessageDialog( this, "Please enter a valid description.",
-                "Invalid description", JOptionPane.ERROR_MESSAGE );
-            return false;
-        }
-        m_sampleDescription = description;
-        
-        // Check the interval.
-        boolean intervalOk = true;
-        long interval = 0;
-        try
-        {
-            interval = Long.parseLong( m_intervalField.getText().trim() );
-        }
-        catch ( NumberFormatException e )
-        {
-            intervalOk = false;
-        }
-        if ( ( interval < 100 ) || ( interval > 24 * 60 * 60 * 1000 ) )
-        {
-            intervalOk = false;
-        }
-        if ( !intervalOk )
-        {
-            JOptionPane.showMessageDialog( this, "Please enter a valid interval. (100ms - 24hrs, 86400000)",
-                "Invalid interval", JOptionPane.ERROR_MESSAGE );
-            return false;
-        }
-        m_interval = interval;
-        
-        // Check the size.
-        boolean sizeOk = true;
-        int size = 0;
-        try
-        {
-            size = Integer.parseInt( m_sizeField.getText().trim() );
-        }
-        catch ( NumberFormatException e )
-        {
-            sizeOk = false;
-        }
-        if ( ( size < 1 ) || ( size > 2048 ) )
-        {
-            sizeOk = false;
-        }
-        if ( !sizeOk )
-        {
-            JOptionPane.showMessageDialog( this, "Please enter a valid size. (1 - 2048)",
-                "Invalid size", JOptionPane.ERROR_MESSAGE );
-            return false;
-        }
-        m_size = size;
-        
-        // Check the leaseTime.
-        boolean leaseTimeOk = true;
-        int leaseTime = 0;
-        try
-        {
-            leaseTime = Integer.parseInt( m_leaseTimeField.getText().trim() );
-        }
-        catch ( NumberFormatException e )
-        {
-            leaseTimeOk = false;
-        }
-        if ( ( leaseTime < 60 ) || ( leaseTime > ( size * interval / 1000 ) + 86400 ) )
-        {
-            leaseTimeOk = false;
-        }
-        if ( !leaseTimeOk )
-        {
-            JOptionPane.showMessageDialog( this, "Please enter a valid lease time. Must be " +
-                "between 1 minute (60) and 24 hours greater than the interval * size (" +
-                ( ( size * interval / 1000 ) + 86400 ) + ")",
-                "Invalid leaseTime", JOptionPane.ERROR_MESSAGE );
-            return false;
-        }
-        m_leaseTime = leaseTime * 1000L;
-        
-        // Store the sample type
-        if ( m_sampleTypeCounter.isSelected() )
-        {
-             m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_COUNTER;
-        }
-        else if ( m_sampleTypeMaximum.isSelected() )
-        {
-             m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MAXIMUM;
-        }
-        else if ( m_sampleTypeMean.isSelected() )
-        {
-             m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MEAN;
-        }
-        else if ( m_sampleTypeMinimum.isSelected() )
-        {
-             m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MINIMUM;
-        }
-        else
-        {
-            // Should never get here.
-            m_sampleType = -1;
-        }
-        
-        return true;
+        return validateFields( false );
     }
     
     /*---------------------------------------------------------------
@@ -238,6 +163,26 @@
      */
     protected Component[] getMainPanelComponents()
     {
+        DocumentListener dl = new DocumentListener() {
+            public void changedUpdate( DocumentEvent event )
+            {
+            }
+            public void insertUpdate( DocumentEvent event )
+            {
+                CreateSampleDialog.this.validateFields( true );
+            }
+            public void removeUpdate( DocumentEvent event )
+            {
+                // When the description is replaced, a remove event is fired when its
+                //  value is "".  If we validate on that then we will go into an infinite
+                //  loop.
+                if ( m_sampleDescriptionField.getText().length() > 0 )
+                {
+                    CreateSampleDialog.this.validateFields( true );
+                }
+            }
+        };
+        
         m_instrumentNameField = new JTextField();
         m_instrumentNameField.setColumns( 40 );
         m_instrumentNameField.setEditable( false );
@@ -248,28 +193,51 @@
         
         m_sampleDescriptionField = new JTextField();
         m_sampleDescriptionField.setColumns( 40 );
+        m_sampleDescriptionField.getDocument().addDocumentListener( dl );
         
         m_intervalField = new JTextField();
         m_intervalField.setColumns( 10 );
+        m_intervalField.getDocument().addDocumentListener( dl );
         
         m_sizeField = new JTextField();
         m_sizeField.setColumns( 4 );
+        m_sizeField.getDocument().addDocumentListener( dl );
         
         m_leaseTimeField = new JTextField();
         m_leaseTimeField.setColumns( 10 );
+        m_leaseTimeField.getDocument().addDocumentListener( dl );
         
         m_maintainLeaseCheckBox = new JCheckBox();
         
         m_sampleTypePanel = Box.createVerticalBox();
         
+        // Create a series of buttons to help the users work efficiently
+        Box intervalBar = Box.createHorizontalBox();
+        intervalBar.add( m_intervalField );
+        intervalBar.add( Box.createHorizontalStrut( 20 ) );
+        intervalBar.add( createIntervalButton( "1 Second", 1000, 600, 600 ) );
+        intervalBar.add( Box.createHorizontalStrut( 5 ) );
+        intervalBar.add( createIntervalButton( "1 Minute", 60000, 1440, 86400 ) );
+        intervalBar.add( Box.createHorizontalStrut( 5 ) );
+        intervalBar.add( createIntervalButton( "1 Hour", 3600000, 672, 86400 ) );
+        
+        Box leaseTimeBar = Box.createHorizontalBox();
+        leaseTimeBar.add( m_leaseTimeField );
+        leaseTimeBar.add( Box.createHorizontalStrut( 20 ) );
+        leaseTimeBar.add( createLeaseTimeButton( "10 Minutes", 600 ) );
+        leaseTimeBar.add( Box.createHorizontalStrut( 5 ) );
+        leaseTimeBar.add( createLeaseTimeButton( "1 Hour", 3600 ) );
+        leaseTimeBar.add( Box.createHorizontalStrut( 5 ) );
+        leaseTimeBar.add( createLeaseTimeButton( "1 Day", 86400 ) );
+        
         return new Component[]
         {
             m_instrumentNameField,
             m_instrumentDescriptionField,
             m_sampleDescriptionField,
-            m_intervalField,
+            intervalBar,
             m_sizeField,
-            m_leaseTimeField,
+            leaseTimeBar,
             m_maintainLeaseCheckBox,
             m_sampleTypePanel
         };
@@ -278,27 +246,69 @@
     /*---------------------------------------------------------------
      * Methods
      *-------------------------------------------------------------*/
+    private JButton createIntervalButton( final String label,
+                                          final long interval,
+                                          final int size,
+                                          final long leaseTime )
+    {
+        Action action = new AbstractAction( label )
+        {
+            public void actionPerformed( ActionEvent event )
+            {
+                CreateSampleDialog.this.setInterval( interval );
+                CreateSampleDialog.this.setSampleCount( size );
+                CreateSampleDialog.this.setLeaseTime( leaseTime );
+            }
+        };
+        return new JButton( action );
+    }
+    
+    private JButton createLeaseTimeButton( final String label,
+                                           final long leaseTime )
+    {
+        Action action = new AbstractAction( label )
+        {
+            public void actionPerformed( ActionEvent event )
+            {
+                CreateSampleDialog.this.setLeaseTime( leaseTime );
+            }
+        };
+        return new JButton( action );
+    }
+    
     /**
      * Builds the sample type component.
      */
     private void buildSampleTypeComponent()
     {
+        ChangeListener cl = new ChangeListener()
+        {
+            public void stateChanged( ChangeEvent event )
+            {
+                if ( ((JRadioButton)event.getSource()).isSelected() )
+                {
+                    // Only validate on the selected value
+                    CreateSampleDialog.this.validateFields( true );
+                }
+            }
+        };
+        
         m_sampleTypeGroup = new ButtonGroup();
         m_sampleTypeCounter = new JRadioButton( "Count over each sample" );
         m_sampleTypeMaximum = new JRadioButton( "Maximum value over each sample" );
         m_sampleTypeMinimum = new JRadioButton( "Minumum value over each sample" );
         m_sampleTypeMean    = new JRadioButton( "Mean value over each sample" );
         
-        switch ( m_instrumentDescriptor.getType() )
+        switch ( m_instrumentType )
         {
-        case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
+        case InstrumentData.INSTRUMENT_TYPE_COUNTER:
             m_sampleTypePanel.add( m_sampleTypeCounter );
             m_sampleTypeGroup.add( m_sampleTypeCounter );
             
             m_sampleTypeCounter.setSelected( true );
-            m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_COUNTER;
+            m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER;
             break;
-        case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
+        case InstrumentData.INSTRUMENT_TYPE_VALUE:
             m_sampleTypePanel.add( m_sampleTypeMaximum );
             m_sampleTypeGroup.add( m_sampleTypeMaximum );
             
@@ -309,12 +319,19 @@
             m_sampleTypeGroup.add( m_sampleTypeMean );
             
             m_sampleTypeMaximum.setSelected( true );
-            m_sampleType = InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MAXIMUM;
+            m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM;
             break;
         default:
             // Unknown Type
             break;
         }
+        
+        // Add the change listeners down here so the initialization does not cause
+        //  them to fire.
+        m_sampleTypeCounter.addChangeListener( cl );
+        m_sampleTypeMaximum.addChangeListener( cl );
+        m_sampleTypeMinimum.addChangeListener( cl );
+        m_sampleTypeMean.addChangeListener( cl );
     }
     
     /**
@@ -326,6 +343,9 @@
     {
         m_sampleDescription = sampleDescription;
         m_sampleDescriptionField.setText( sampleDescription );
+        
+        // Validate the fields quietly to update other values correctly.
+        validateFields( true );
     }
     
     /**
@@ -347,6 +367,9 @@
     {
         m_interval = interval;
         m_intervalField.setText( Long.toString( interval ) );
+        
+        // Validate the fields quietly to update other values correctly.
+        validateFields( true );
     }
     
     /**
@@ -431,23 +454,26 @@
     {
         m_sampleType = type;
         
-        switch(type)
+        switch ( type )
         {
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_COUNTER:
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER:
             m_sampleTypeCounter.setSelected( true );
             break;
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
             m_sampleTypeMaximum.setSelected( true );
             break;
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MEAN:
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MEAN:
             m_sampleTypeMean.setSelected( true );
             break;
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
             m_sampleTypeMinimum.setSelected( true );
             break;
         default:
             break;
         }
+        
+        // Validate the fields quietly to update other values correctly.
+        validateFields( true );
     }
     
     /**
@@ -458,6 +484,166 @@
     int getSampleType()
     {
         return m_sampleType;
+    }
+    
+    /**
+     * Goes through and validates the fields in the dialog.
+     *
+     * @param quiet True if problems should be ignored.
+     * 
+     * @return True if the fields were Ok.
+     */
+    private boolean validateFields( boolean quiet )
+    {
+        // Check the interval.
+        boolean intervalOk = true;
+        long interval = 0;
+        try
+        {
+            interval = Long.parseLong( m_intervalField.getText().trim() );
+        }
+        catch ( NumberFormatException e )
+        {
+            intervalOk = false;
+        }
+        if ( ( interval < 100 ) || ( interval > 24 * 60 * 60 * 1000 ) )
+        {
+            intervalOk = false;
+        }
+        if ( intervalOk )
+        {
+            m_interval = interval;
+            m_intervalField.setForeground( null );
+        }
+        else
+        {
+            m_intervalField.setForeground( Color.red );
+            if ( !quiet )
+            {
+                JOptionPane.showMessageDialog( this, "Please enter a valid interval. (100ms - 24hrs, 86400000)",
+                    "Invalid interval", JOptionPane.ERROR_MESSAGE );
+                return false;
+            }
+        }
+        
+        // Check the size.
+        boolean sizeOk = true;
+        int size = 0;
+        try
+        {
+            size = Integer.parseInt( m_sizeField.getText().trim() );
+        }
+        catch ( NumberFormatException e )
+        {
+            sizeOk = false;
+        }
+        if ( ( size < 1 ) || ( size > 2048 ) )
+        {
+            sizeOk = false;
+        }
+        if ( sizeOk )
+        {
+            m_size = size;
+            m_sizeField.setForeground( null );
+        }
+        else
+        {
+            m_sizeField.setForeground( Color.red );
+            if ( !quiet )
+            {
+                JOptionPane.showMessageDialog( this, "Please enter a valid size. (1 - 2048)",
+                    "Invalid size", JOptionPane.ERROR_MESSAGE );
+                return false;
+            }
+        }
+        
+        // Check the leaseTime.
+        boolean leaseTimeOk = true;
+        int leaseTime = 0;
+        try
+        {
+            leaseTime = Integer.parseInt( m_leaseTimeField.getText().trim() );
+        }
+        catch ( NumberFormatException e )
+        {
+            leaseTimeOk = false;
+        }
+        if ( ( leaseTime < 60 ) || ( leaseTime > ( size * interval / 1000 ) + 86400 ) )
+        {
+            leaseTimeOk = false;
+        }
+        if ( leaseTimeOk )
+        {
+            m_leaseTime = leaseTime * 1000L;
+            m_leaseTimeField.setForeground( null );
+        }
+        else
+        {
+            m_leaseTimeField.setForeground( Color.red );
+            if ( !quiet )
+            {
+                JOptionPane.showMessageDialog( this, "Please enter a valid lease time. Must be " +
+                    "between 1 minute (60) and 24 hours greater than the interval * size (" +
+                    ( ( size * interval / 1000 ) + 86400 ) + ")",
+                    "Invalid leaseTime", JOptionPane.ERROR_MESSAGE );
+                return false;
+            }
+        }
+        
+        // Store the sample type
+        if ( m_sampleTypeCounter.isSelected() )
+        {
+             m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER;
+        }
+        else if ( m_sampleTypeMaximum.isSelected() )
+        {
+             m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM;
+        }
+        else if ( m_sampleTypeMean.isSelected() )
+        {
+             m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MEAN;
+        }
+        else if ( m_sampleTypeMinimum.isSelected() )
+        {
+             m_sampleType = InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MINIMUM;
+        }
+        else
+        {
+            // Should never get here.
+            m_sampleType = -1;
+        }
+        
+        // Update the default description
+        String newDefaultDescription =
+            InstrumentSampleUtils.getDefaultDescriptionForType( m_sampleType, m_interval );
+        
+        // Check the description.
+        String description = m_sampleDescriptionField.getText().trim();
+        if ( ( description.length() == 0 ) || ( description.equals( m_lastDefaultDescription ) ) )
+        {
+            if ( !description.equals( newDefaultDescription ) )
+            {
+                // Set the description to the default.
+                description = newDefaultDescription;
+                
+                // We can't change the description field directly because this is called from
+                //  its change listener.
+                final String setDesc = description;
+                SwingUtilities.invokeLater( new Runnable()
+                    {
+                        public void run()
+                        {
+                            CreateSampleDialog.this.m_sampleDescriptionField.setText( setDesc );
+                        }
+                    } );
+            }
+        }
+        m_sampleDescription = description;
+        
+        // Always remember the new default description
+        m_lastDefaultDescription = newDefaultDescription;
+        
+        return true;
     }
 }
 

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Data.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Data.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,55 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+/**
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
+ * @since 4.1
+ */
+public interface Data
+{
+    /**
+     * Returns the description.
+     *
+     * @return The description.
+     */
+    String getDescription();
+    
+    /**
+     * Returns the state version.
+     *
+     * @return The state version.
+     */
+    int getStateVersion();
+    
+    /**
+     * Causes the Data to update itself with the latest data from the server.
+     *
+     * @return true if successful.
+     */
+    boolean update();
+}

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ElementData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/ElementData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,56 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+/**
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
+ * @since 4.1
+ */
+public interface ElementData
+    extends Data
+{
+    /**
+     * Returns the parent data object.
+     *
+     * @return The parent data object.
+     */
+    Data getParent();
+    
+    /**
+     * Returns the name.
+     *
+     * @return The name.
+     */
+    String getName();
+    
+    /**
+     * Returns the configured flag of the remote object.
+     *
+     * @return The configured flag of the remote object.
+     */
+    boolean isConfigured();
+}

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentClientFrame.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentClientFrame.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentClientFrame.java	Tue Jul 27 10:37:36 2004
@@ -29,6 +29,8 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -50,9 +52,12 @@
 import org.apache.avalon.framework.configuration.DefaultConfiguration;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
+import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.avalon.framework.logger.LogEnabled;
 import org.apache.avalon.framework.logger.Logger;
 
+import org.apache.excalibur.instrument.client.http.HTTPInstrumentManagerConnection;
+
 /**
  *
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
@@ -63,8 +68,9 @@
     extends JFrame
     implements Runnable, InstrumentManagerConnectionListener, LogEnabled
 {
-    static final String SHUTDOWN_HOOK_NAME = "InstrumentClientShutdownHook";
+    protected static final String MEDIA_PATH = "org/apache/excalibur/instrument/client/media/";
     
+    static final String SHUTDOWN_HOOK_NAME = "InstrumentClientShutdownHook";
     
     private String m_title;
     
@@ -79,7 +85,6 @@
     
     private HashMap m_connections = new HashMap();
     private InstrumentManagerConnection[] m_connectionArray;
-
     
     /** Shutdown hook */
     private Thread m_hook;
@@ -100,15 +105,17 @@
         super();
 
         m_title = title;
-        
+    }
+    
+    public void initialize()
+    {
         init();
-
+        
         m_runner = new Thread( this, "InstrumentClientFrameRunner" );
         m_runner.start();
         
-        ClassLoader cl = InstrumentManagerTreeCellRenderer.class.getClassLoader();
-        setIconImage( new ImageIcon( cl.getResource(
-            NodeData.MEDIA_PATH + "client.gif") ).getImage() );
+        ClassLoader cl = this.getClass().getClassLoader();
+        setIconImage( new ImageIcon( cl.getResource( MEDIA_PATH + "client.gif") ).getImage() );
     }
     
     /*---------------------------------------------------------------
@@ -132,29 +139,23 @@
                     }
                 }
                 
-                // Check on the status of all of the connections (Avoid synchronization)
-                InstrumentManagerConnection[] connectionArray = getInstrumentManagerConnections();
-                for ( int i = 0; i < connectionArray.length; i++ )
+                // Update each of the InstrumentManagerConnections.
+                InstrumentManagerConnection[] connections = getConnections();
+                for ( int i = 0; i < connections.length; i++ )
                 {
-                    InstrumentManagerConnection connection = connectionArray[i];
-                    if ( connection.isClosed() )
-                    {
-                        // Connection is closed, try to open it.
-                        connection.tryOpen();
-                    }
-                    else
+                    InstrumentManagerConnection connection = connections[i];
+                    connection.update();
+                    
+                    // Update the tab title.
+                    int tabIndex = m_connectionsPane.indexOfComponent( connection );
+                    if ( tabIndex >= 0 )
                     {
-                        // Make sure that the connection is still open
-                        if ( connection.ping() )
-                        {
-                            // Still connected
-                            connection.handleLeasedSamples();
-                        }
+                        m_connectionsPane.setTitleAt( tabIndex, connection.getTabTitle() );
+                        m_connectionsPane.setToolTipTextAt( tabIndex, connection.getTabTooltip() );
                     }
                 }
-
-                // Update each of the ProfileSampleFrames.  This is kind of temporary
-                //  to get rid of the one thread per frame issue.
+                
+                // Update each of the InstrumentSampleFrames.
                 JInternalFrame[] frames = m_desktopPane.getAllFrames();
                 for( int i = 0; i < frames.length; i++ )
                 {
@@ -170,6 +171,19 @@
             {
                 // Should not get here, but we want to make sure that this never happens.
                 getLogger().error( "Unexpected error caught in InstrumentClientFrame runner:", t );
+                
+                // Avoid thrashing.
+                try
+                {
+                    Thread.sleep( 5000 );
+                }
+                catch ( InterruptedException e )
+                {
+                    if ( m_runner == null )
+                    {
+                        return;
+                    }
+                }
             }
         }
     }
@@ -190,7 +204,7 @@
         if ( tabIndex >= 0 )
         {
             m_connectionsPane.setTitleAt( tabIndex, connection.getTabTitle() );
-            m_connectionsPane.setToolTipTextAt( tabIndex, connection.getTitle() );
+            m_connectionsPane.setToolTipTextAt( tabIndex, connection.getTabTooltip() );
         }
     }
     
@@ -207,7 +221,7 @@
         if ( tabIndex >= 0 )
         {
             m_connectionsPane.setTitleAt( tabIndex, connection.getTabTitle() );
-            m_connectionsPane.setToolTipTextAt( tabIndex, connection.getTitle() );
+            m_connectionsPane.setToolTipTextAt( tabIndex, connection.getTabTooltip() );
         }
     }
     
@@ -230,8 +244,8 @@
         }
         
         connection.removeInstrumentManagerConnectionListener( this );
-        String key = connection.getHost() + ":" + connection.getPort();
-        synchronized (m_connections)
+        Object key = connection.getKey();
+        synchronized ( m_connections )
         {
             m_connections.remove( key );
             m_connectionArray = null;
@@ -279,7 +293,9 @@
             }
             catch( Exception e )
             {
-                showErrorDialog( "Unable to load desktop file.", e );
+                String msg = "Unable to load desktop file.";
+                getLogger().debug( msg, e );
+                showErrorDialog( msg, e );
             }
             updateTitle();
         }
@@ -372,6 +388,7 @@
             String msg = "Unable to fully load the frame state.";
             if ( showErrorDialog )
             {
+                getLogger().debug( msg, e );
                 showErrorDialog( msg, e );
             }
             else
@@ -388,32 +405,40 @@
         for( int i = 0; i < connConfs.length; i++ )
         {
             Configuration connConf = connConfs[ i ];
-            String host = connConf.getAttribute( "host" );
-            int port = connConf.getAttributeAsInteger( "port" );
-            String key = getInstrumentManagerConnectionKey( host, port );
+            String tURL = connConf.getAttribute( "url" );
+            URL url;
+            try
+            {
+                url = new URL( tURL );
+            }
+            catch ( MalformedURLException e )
+            {
+                throw new ConfigurationException( "Invalid url, '" + tURL + "'", e );
+            }
             
-            InstrumentManagerConnection connection;
-            synchronized (m_connections)
+            InstrumentManagerConnection conn;
+            synchronized ( m_connections )
             {
-                connection = (InstrumentManagerConnection)m_connections.get( key );
+                conn = (InstrumentManagerConnection)m_connections.get( url );
                 
-                if ( connection == null )
+                if ( conn == null )
                 {
-                    // Need to create a new connection.
-                    connection = createInstrumentManagerConnection( host, port );
+                    // Need to create a new connection
+                    conn = createConnection( url );
                 }
             }
             
             // Load the state into the connection.
             try
             {
-                connection.loadState( connConf );
+                conn.loadState( connConf );
             }
             catch ( ConfigurationException e )
             {
-                String msg = "Unable to fully load the state of connection, " + key;
+                String msg = "Unable to fully load the state of connection, " + conn.getKey();
                 if ( showErrorDialog )
                 {
+                    getLogger().debug( msg, e );
                     showErrorDialog( msg, e );
                 }
                 else
@@ -433,17 +458,26 @@
             if ( type.equals( InstrumentSampleFrame.FRAME_TYPE ) )
             {
                 // Figure out which connection the frame will belong to.
-                String host = frameConf.getAttribute( "host" );
-                int port = frameConf.getAttributeAsInteger( "port" );
-                InstrumentManagerConnection connection =
-                    getInstrumentManagerConnection( host, port );
+                String tURL = frameConf.getAttribute( "url" );
+                URL url;
+                try
+                {
+                    url = new URL( tURL );
+                }
+                catch ( MalformedURLException e )
+                {
+                    throw new ConfigurationException( "Invalid url, '" + tURL + "'", e );
+                }
+                
+                InstrumentManagerConnection connection = getConnection( url );
                 if ( connection == null )
                 {
                     // Connection not found.
                     String msg = "Sample frame not being loaded becase no connection to " +
-                        host + ":" + port + " exists.";
+                        url.toExternalForm() + " exists.";
                     if ( showErrorDialog )
                     {
+                        getLogger().debug( msg );
                         showErrorDialog( msg );
                     }
                     else
@@ -458,10 +492,12 @@
                     }
                     catch ( ConfigurationException e )
                     {
-                        String msg = "Unable to fully load the state of an inner frame for sample: " +
+                        String msg =
+                            "Unable to fully load the state of an inner frame for sample: " +
                             frameConf.getAttribute( "sample", "Sample name missing" );
                         if ( showErrorDialog )
                         {
+                            getLogger().debug( msg, e );
                             showErrorDialog( msg, e );
                         }
                         else
@@ -601,10 +637,10 @@
         state.addChild( frameState );
         
         // Save the state of any connections.
-        InstrumentManagerConnection[] connections = getInstrumentManagerConnections();
+        InstrumentManagerConnection[] connections = getConnections();
         for ( int i = 0; i < connections.length; i++ )
         {
-            state.addChild( connections[ i ].saveState() );
+            state.addChild( connections[i].saveState() );
         }
         
         // Save the state of any inner frames.
@@ -681,8 +717,12 @@
         Toolkit toolkit = getToolkit();
         Dimension screenSize = toolkit.getScreenSize();
         
-        setLocation( 20, 20 );
-        setSize( (int)(screenSize.width * 0.9), (int)(screenSize.height * 0.9) );
+        // Set the default size and location of the window.  This will be overridden
+        //  by whatever is stored in a state file if loaded.
+        int screenWidth = screenSize.width;
+        int screenHeight = screenSize.height;
+        setLocation( screenWidth / 20, screenHeight / 20 );
+        setSize( screenWidth * 9 / 10, screenHeight * 8 / 10 );
     }
     
     private void updateTitle()
@@ -851,35 +891,27 @@
         reorganizeFrames( 1, count, openFrames );
     }
     
-    InstrumentManagerConnection[] getInstrumentManagerConnections()
+    InstrumentManagerConnection[] getConnections()
     {
         // Avoid synchronization when possible.
         InstrumentManagerConnection[] array = m_connectionArray;
         if ( array == null )
         {
-            array = updateInstrumentManagerConnectionArray();
+            synchronized ( m_connections )
+            {
+                m_connectionArray = new InstrumentManagerConnection[m_connections.size()];
+                m_connections.values().toArray( m_connectionArray );
+                array = m_connectionArray;
+            }
         }
         return array;
     }
     
-    private InstrumentManagerConnection[] updateInstrumentManagerConnectionArray()
-    {
-        synchronized (this)
-        {
-            InstrumentManagerConnection[] array =
-                new InstrumentManagerConnection[ m_connections.size() ];
-            m_connections.values().toArray( array );
-            m_connectionArray = array;
-            return array;
-        }
-    }
-    
-    InstrumentManagerConnection getInstrumentManagerConnection( String host, int port )
+    InstrumentManagerConnection getConnection( URL url )
     {
-        String key = host + ":" + port;
-        synchronized (m_connections)
+        synchronized ( m_connections )
         {
-            return (InstrumentManagerConnection)m_connections.get( key );
+            return (InstrumentManagerConnection)m_connections.get( url );
         }
     }
     
@@ -889,100 +921,58 @@
         {
             public void run()
             {
+                URL defaultURL;
+                try
+                {
+                    defaultURL = new URL( "http://localhost:15080" );
+                }
+                catch ( MalformedURLException e )
+                {
+                    // Should never happen.
+                    e.printStackTrace();
+                    return;
+                }
+                
                 ConnectDialog dialog = new ConnectDialog( InstrumentClientFrame.this );
-                dialog.setHost( "localhost" );
-                dialog.setPort( 15555 );
+                dialog.setURL( defaultURL );
                 dialog.show();
                 if ( dialog.getAction() == ConnectDialog.BUTTON_OK )
                 {
-                    openInstrumentManagerConnection( dialog.getHost(), dialog.getPort() );
+                    synchronized( m_connections )
+                    {
+                        createConnection( dialog.getURL() );
+                    }
                 }
             }
         } );
     }
     
     /**
-     * Returns the key used to access connections in the connections map.
-     *
-     * @return The key used to access connections in the connections map.
-     */
-    private String getInstrumentManagerConnectionKey( String host, int port )
-    {
-        return host + ":" + port;
-    }
-    
-    /**
      * Creates an registers a new InstrumentManagerConnection.  This method
      *  should never be called in the connection already exists.  Caller must
      *  ensure that m_connections is synchronized.
      *
-     * @param host Host of the connecton.
-     * @param port Port of the connecton.
+     * @param url URL of the connecton.
      *
      * @return The new InstrumentManagerConnection
      */
-    private InstrumentManagerConnection createInstrumentManagerConnection( String host, int port )
+    private InstrumentManagerConnection createConnection( URL url )
     {
-        String key = getInstrumentManagerConnectionKey( host, port );
-        InstrumentManagerConnection connection =
-            new InstrumentManagerConnection( this, host, port );
-        connection.enableLogging( getLogger() );
-        m_connections.put( key, connection );
+        InstrumentManagerConnection conn = new HTTPInstrumentManagerConnection( url );
+        ContainerUtil.enableLogging(
+            conn, getLogger().getChildLogger( url.getHost() + ":" + url.getPort() ) );
+        conn.setFrame( this );
+        conn.init();
+        m_connections.put( conn.getKey(), conn );
         m_connectionArray = null;
         
-        connection.addInstrumentManagerConnectionListener(
-            InstrumentClientFrame.this );
+        conn.addInstrumentManagerConnectionListener( this );
         
-        m_connectionsPane.add( connection.getTabTitle(), connection );
+        m_connectionsPane.add( conn.getTabTitle(), conn );
         
-        return connection;
-    }
-    
-    void openInstrumentManagerConnection( final String host, final int port )
-    {
-        SwingUtilities.invokeLater( new Runnable()
-        {
-            public void run()
-            {
-                String key = getInstrumentManagerConnectionKey( host, port );
-                synchronized (m_connections)
-                {
-                    InstrumentManagerConnection connection =
-                        (InstrumentManagerConnection)m_connections.get( key );
-                    if ( connection == null )
-                    {
-                        createInstrumentManagerConnection( host, port );
-                        
-                        return;
-                    }
-                }
-                
-                // If we get here show an error that the connection alreay exists.
-                //  Must be done outside the synchronization block.
-                showErrorDialog( "A connection to " + key + " already exists." );
-            }
-        } );
+        return conn;
     }
     
-    /*
-    void openInstrumentSampleFrame( final InstrumentManagerConnection connection,
-                                    final InstrumentSampleDescriptor instrumentSampleDescriptor )
-    {
-        SwingUtilities.invokeLater( new Runnable()
-        {
-            public void run()
-            {
-                String sampleName = instrumentSampleDescriptor.getName();
-                InstrumentSampleFrame frame = new InstrumentSampleFrame( connection,
-                    sampleName, InstrumentClientFrame.this );
-
-                frame.addToDesktop( m_desktopPane );
-                frame.show();
-            }
-        } );
-    }
-    */
-    
     private void showErrorDialog( String message )
     {
         JOptionPane.showMessageDialog( this,
@@ -1024,14 +1014,10 @@
         }
         
         // Stop the runner.
-        m_runner.interrupt();
-        m_runner = null;
-        
-        // Close all connections cleanly.
-        InstrumentManagerConnection[] connections = getInstrumentManagerConnections();
-        for ( int i = 0; i < connections.length; i++ )
+        if ( m_runner != null )
         {
-            connections[i].delete();
+            m_runner.interrupt();
+            m_runner = null;
         }
         
         if ( !fallThrough )
@@ -1105,7 +1091,9 @@
             }
             catch( Exception e )
             {
-                showErrorDialog( "Unable to load desktop file.", e );
+                String msg = "Unable to load desktop file.";
+                getLogger().debug( msg, e );
+                showErrorDialog( msg, e );
             }
             updateTitle();
         }
@@ -1121,7 +1109,9 @@
             }
             catch( Exception e )
             {
-                showErrorDialog( "Unable to save desktop file.", e );
+                String msg = "Unable to save desktop file.";
+                getLogger().debug( msg, e );
+                showErrorDialog( msg, e );
             }
         }
         else
@@ -1187,7 +1177,9 @@
             }
             catch( Exception e )
             {
-                showErrorDialog( "Unable to save desktop file.", e );
+                String msg = "Unable to save desktop file.";
+                getLogger().debug( msg, e );
+                showErrorDialog( msg, e );
             }
             updateTitle();
         }

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,70 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentData
+    extends ElementData
+{
+    /** Type which specifies that the type of a Instrument has not yet been determined. */
+    int INSTRUMENT_TYPE_NONE = 0;
+    
+    /** Type which identifies CounterInstruments. */
+    int INSTRUMENT_TYPE_COUNTER = 1;
+    
+    /** Type which identifies ValueInstruments. */
+    int INSTRUMENT_TYPE_VALUE   = 2;
+    
+    /**
+     * Returns the registered flag of the remote object.
+     *
+     * @return The registered flag of the remote object.
+     */
+    boolean isRegistered();
+    
+    /**
+     * Returns the type of the Instrument.  Possible values include
+     *  InstrumentData.INSTRUMENT_TYPE_COUNTER,
+     *  InstrumentData.INSTRUMENT_TYPE_VALUE or
+     *  InstrumentData.INSTRUMENT_TYPE_NONE, if the type was never set.
+     *
+     * @return The type of the Instrument.
+     */
+    int getType();
+    
+    /**
+     * Returns an array of the Instrument Samples assigned to the Instrument.
+     *
+     * @return An array of Instrument Samples.
+     */
+    InstrumentSampleData[] getInstrumentSamples();
+    
+    /**
+     * Requests that a sample be created or that its lease be updated.
+     *
+     * @param description Description to assign to the new sample.
+     * @param interval Sample interval of the new sample.
+     * @param sampleCount Number of samples in the new sample.
+     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param sampleType The type of sample to be created.
+     */
+    void createInstrumentSample( String description,
+                                 long interval,
+                                 int sampleCount,
+                                 long leaseTime,
+                                 int sampleType );
+}

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java	Tue Jul 27 10:37:36 2004
@@ -22,9 +22,10 @@
 import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
 import java.beans.PropertyVetoException;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import javax.swing.AbstractAction;
 import javax.swing.Action;
@@ -42,45 +43,28 @@
 import org.apache.avalon.framework.logger.LogEnabled;
 import org.apache.avalon.framework.logger.Logger;
 
-import org.apache.altrmi.client.HostContext;
-import org.apache.altrmi.client.Factory;
-import org.apache.altrmi.client.impl.socket.SocketCustomStreamHostContext;
-import org.apache.altrmi.client.impl.ClientSideClassFactory;
-import org.apache.altrmi.common.ConnectionException;
-import org.apache.altrmi.client.InvocationException;
-import org.apache.altrmi.client.ConnectionRefusedException;
-
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleSnapshot;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleUtils;
-
 /**
+ * A Connection to the remote InstrumentManager.
  *
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
- * @version CVS $Revision: 1.5 $ $Date: 2004/02/29 18:11:04 $
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
  * @since 4.1
  */
-class InstrumentManagerConnection
+public abstract class InstrumentManagerConnection
     extends JComponent
     implements LogEnabled
 {
-    protected final InstrumentClientFrame m_frame;
-    private final String m_host;
-    private final int m_port;
-
     private Logger m_logger;
-
-    private boolean m_closed;
-    private boolean m_deleted;
-    private HostContext m_altrmiHostContext;
-    private Factory m_altrmiFactory;
-    private InstrumentManagerClient m_manager;
-    protected InstrumentManagerTreeModel m_treeModel;
+    private InstrumentManagerTreeModel m_treeModel;
     private InstrumentManagerTree m_tree;
+    
+    private InstrumentClientFrame m_frame;
+    
+    private boolean m_deleted;
+    
+    private JLabel m_descriptionLabel;
 
-    private final ArrayList m_listeners = new ArrayList();
+    private final List m_listeners = new ArrayList();
     private InstrumentManagerConnectionListener[] m_listenerArray = null;
 
     private long m_lastLeaseRenewalTime;
@@ -88,20 +72,62 @@
     private MaintainedSampleLease[] m_maintainedSampleLeaseArray = null;
 
     /** Maintain a list of all sample frames which are viewing data in this connection. */
-    private HashMap m_sampleFrames = new HashMap();
-
+    private Map m_sampleFrames = new HashMap();
+    
     /*---------------------------------------------------------------
      * Constructors
      *-------------------------------------------------------------*/
-    InstrumentManagerConnection( InstrumentClientFrame frame, String host, int port )
+    /**
+     * Creates a new InstrumentManagerConnection.
+     */
+    public InstrumentManagerConnection()
     {
-        m_frame = frame;
-        m_host = host;
-        m_port = port;
-        m_closed = true;
+    }
+    
+
+    /*---------------------------------------------------------------
+     * LogEnabled Methods
+     *-------------------------------------------------------------*/
+    public void enableLogging( Logger logger )
+    {
+        m_logger = logger.getChildLogger( "conn_" + getKey() );
+    }
+
+    protected Logger getLogger()
+    {
+        return m_logger;
+    }
 
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Stores a reference to the client frame.
+     *
+     * @param frame The main client frame.
+     */
+    final void setFrame( InstrumentClientFrame frame )
+    {
+        m_frame = frame;
+    }
+    
+    /**
+     * Returns a reference to the client frame.
+     *
+     * @return A reference to the client frame.
+     */
+    final InstrumentClientFrame getFrame()
+    {
+        return m_frame;
+    }
+    
+    /**
+     * Called to initialize the connection object.
+     */
+    public void init()
+    {
         m_treeModel = new InstrumentManagerTreeModel( this );
-        // Set the logger when the connection logger is set.
+        m_treeModel.enableLogging( m_logger.getChildLogger( "treeModel" ) );
         addInstrumentManagerConnectionListener( m_treeModel );
 
         setLayout( new BorderLayout() );
@@ -110,23 +136,23 @@
         Box topPane = Box.createVerticalBox();
 
         // Top Labels
-        JPanel labels = new JPanel();
-        labels.setLayout( new FlowLayout( FlowLayout.LEFT ) );
-
-        JLabel hostLabelLabel = new JLabel( "Host: " );
-        labels.add( hostLabelLabel );
-        JLabel hostLabel = new JLabel( getHost() );
-        hostLabel.setForeground( Color.black );
-        labels.add( hostLabel );
-
-        JLabel portLabelLabel = new JLabel( "  Port: " );
-        labels.add( portLabelLabel );
-        JLabel portLabel = new JLabel( Integer.toString( getPort() ) );
-        portLabel.setForeground( Color.black );
-        labels.add( portLabel );
-
+        // Row 1
+        Box labels = Box.createHorizontalBox();
+        labels.add( Box.createHorizontalStrut( 4 ) );
+        m_descriptionLabel = new JLabel( getInstrumentManager().getDescription() );
+        labels.add( m_descriptionLabel );
+        labels.add( Box.createHorizontalGlue() );
+        topPane.add( labels );
+        
+        // Row 2
+        labels = Box.createHorizontalBox();
+        labels.add( Box.createHorizontalStrut( 4 ) );
+        labels.add( new JLabel( "URL: " + getKey().toString() ) );
+        labels.add( Box.createHorizontalGlue() );
         topPane.add( labels );
 
+        topPane.add( Box.createVerticalStrut( 4 ) );
+        
         // Top Buttons
         Action gcAction = new AbstractAction( "Invoke GC" )
         {
@@ -158,11 +184,32 @@
         };
         JButton refreshButton = new JButton( refreshAction );
 
-        JPanel buttons = new JPanel();
-        buttons.setLayout( new FlowLayout( FlowLayout.LEFT ) );
+        Action deleteAction = new AbstractAction( "Delete" )
+        {
+            public void actionPerformed( ActionEvent event )
+            {
+                SwingUtilities.invokeLater( new Runnable()
+                    {
+                        public void run()
+                        {
+                            InstrumentManagerConnection.this.delete();
+                        }
+                    });
+            }
+        };
+        JButton deleteButton = new JButton( deleteAction );
+
+        Box buttons = Box.createHorizontalBox();
+        buttons.add( Box.createHorizontalStrut( 4 ) );
         buttons.add ( gcButton );
+        buttons.add( Box.createHorizontalStrut( 4 ) );
         buttons.add ( refreshButton );
+        buttons.add( Box.createHorizontalStrut( 4 ) );
+        buttons.add ( deleteButton );
+        buttons.add( Box.createHorizontalGlue() );
         topPane.add( buttons );
+        
+        topPane.add( Box.createVerticalStrut( 4 ) );
 
         add( topPane, BorderLayout.NORTH );
 
@@ -170,353 +217,180 @@
         m_tree = new InstrumentManagerTree( this );
         add( m_tree, BorderLayout.CENTER );
     }
-
-    /*---------------------------------------------------------------
-     * LogEnabled Methods
-     *-------------------------------------------------------------*/
-    public void enableLogging( Logger logger )
+    
+    /**
+     * Returns true once the connection has been deleted.
+     *
+     * @return True if deleted.
+     */
+    public boolean isDeleted()
     {
-        m_logger = logger.getChildLogger( "conn_" + m_host + "_" + m_port );
-        m_treeModel.enableLogging( m_logger.getChildLogger( "treeModel" ) );
+        return m_deleted;
     }
-
-    Logger getLogger()
+    
+    /**
+     * Returns the title to display in the tab for the connection.
+     *
+     * @return The tab title.
+     */
+    public String getTabTitle()
     {
-        return m_logger;
+        return getInstrumentManager().getName();
     }
-
-    /*---------------------------------------------------------------
-     * Methods
-     *-------------------------------------------------------------*/
-    String getTabTitle()
+    
+    /**
+     * Returns the tooltip to display in the tab for the connection.
+     *
+     * @return The tab tooltip.
+     */
+    public String getTabTooltip()
     {
-        String tabTitle;
-        InstrumentManagerClient manager = m_manager;
-        if ( manager == null )
+        String key = getKey().toString();
+        String tab = getInstrumentManager().getDescription();
+        
+        if ( key.equals( tab ) )
         {
-            tabTitle = "[Not Connected]";
+            return tab;
         }
         else
         {
-            try
-            {
-                tabTitle = manager.getDescription();
-            }
-            catch ( InvocationException e )
-            {
-                // Connection closed.  Ignore this here.
-                tabTitle = "[Not Connected]";
-            }
+            return tab + " [" + key + "]";
         }
-        return tabTitle;
     }
-
-    String getHost()
-    {
-        return m_host;
-    }
-
-    int getPort()
-    {
-        return m_port;
-    }
-
+    
     /**
-     * Returns a title for the connection which can be used in frame titlesa
-     *  and menus.  Reflects the connected status.
+     * Returns the title for the connection.
+     *
+     * @return The title.
      */
-    String getTitle()
-    {
-        return getTabTitle() + " (" + m_host + ":" + m_port + ")";
-    }
-
-    InstrumentManagerClient getInstrumentManagerClient()
+    public String getTitle()
     {
-        return m_manager;
+        return getInstrumentManager().getDescription();
     }
-
-    InstrumentManagerTreeModel getTreeModel()
-    {
-        return m_treeModel;
-    }
-
+    
     /**
-     * Returns a thread save array representation of the MaintainedSampleLeases.
+     * Returns the key used to identify this object.
      *
-     * @return A thread save array representation of the MaintainedSampleLeases.
+     * @return The key used to identify this object.
      */
-    private MaintainedSampleLease[] getMaintainedSampleLeaseArray()
-    {
-        MaintainedSampleLease[] array = m_maintainedSampleLeaseArray;
-        if ( array == null )
-        {
-            synchronized(this)
-            {
-                m_maintainedSampleLeaseArray =
-                    new MaintainedSampleLease[ m_maintainedSampleLeaseMap.size() ];
-                m_maintainedSampleLeaseMap.values().toArray( m_maintainedSampleLeaseArray );
-                array = m_maintainedSampleLeaseArray;
-            }
-        }
-        return array;
-    }
-
+    public abstract Object getKey();
+    
     /**
-     * Called once each second by the main worker thread of the client.  This
-     *  method is responsible for maintaining and expiring leased samples.
+     * Returns true if connected.
+     *
+     * @return True if connected.
      */
-    void handleLeasedSamples()
-    {
-        // If we are not connected, then there is nothing to be done here.
-
-        // Only renew leases once per minute.
-        long now = System.currentTimeMillis();
-        if ( now - m_lastLeaseRenewalTime > 60000 )
-        {
-            //getLogger().debug("Renew Leases:");
-            MaintainedSampleLease[] leases = getMaintainedSampleLeaseArray();
-            for ( int i = 0; i < leases.length; i++ )
-            {
-                MaintainedSampleLease lease = leases[i];
-                //getLogger().debug(" lease: " + lease.getSampleName());
-
-                // Look for the Sample Descriptor in the Tree Model
-                DefaultMutableTreeNode sampleTreeNode =
-                    m_treeModel.getInstrumentSampleTreeNode( lease.getSampleName() );
-                if ( sampleTreeNode == null )
-                {
-                    // A node does not yet exist for the sample.  We need to
-                    //  create it on the server to make sure that it exists.
-                    //  Then refresh the Instrument in the tree node so that it
-                    //  is created.
-
-                    // Loof for the Instrument Descriptor in the Tree Model
-                    DefaultMutableTreeNode instrumentTreeNode =
-                        m_treeModel.getInstrumentTreeNode( lease.getInstrumentName() );
-                    if ( instrumentTreeNode == null )
-                    {
-                        // Instrument does not exist.  Ignore this for now.
-                    }
-                    else
-                    {
-                        // Get the InstrumentDescriptor
-                        InstrumentDescriptor instrumentDescriptor =
-                            ((InstrumentNodeData)instrumentTreeNode.getUserObject()).
-                            getDescriptor();
-
-                        // Now attempt to create the sample
-                        try
-                        {
-                            instrumentDescriptor.createInstrumentSample(
-                                lease.getDescription(), lease.getInterval(), lease.getSize(),
-                                lease.getLeaseDuration(), lease.getType() );
-
-                            // Refresh the Tree Model
-                            m_treeModel.updateInstrument( instrumentDescriptor, instrumentTreeNode,
-                                -1 /* Force Update */ );
-                        }
-                        catch ( InvocationException e )
-                        {
-                            // Means that the connection died.
-                            close();
-                        }
-                    }
-                }
-                else
-                {
-                    // A sample descriptor already exists.  Simply extend it.
-                    InstrumentSampleNodeData sampleNodeData =
-                        (InstrumentSampleNodeData)sampleTreeNode.getUserObject();
-
-                    // Get the InstrumentSampleDescriptor
-                    InstrumentSampleDescriptor sampleDescriptor = sampleNodeData.getDescriptor();
-
-                    try
-                    {
-                        long newExpireTime =
-                            sampleDescriptor.extendLease( lease.getLeaseDuration() );
-                        //getLogger().debug("  Extended lease to: " + newExpireTime );
-
-                        sampleNodeData.setLeaseExpireTime( newExpireTime );
-
-                        // Refresh the Tree Model
-                        m_treeModel.updateInstrumentSample( sampleDescriptor, sampleTreeNode );
-                    }
-                    catch ( InvocationException e )
-                    {
-                        // Means that the connection died.
-                        close();
-                    }
-
-                }
-            }
-
-            // Also, take this oportunity to update all of the leased samples in
-            //  the model.
-            m_treeModel.renewAllSampleLeases();
-
-            m_lastLeaseRenewalTime = now;
-        }
-
-        // Now have the TreeModel purge any expired samples from the tree.
-        m_treeModel.purgeExpiredSamples();
-    }
-
-    void open() throws ConnectionException, IOException
+    public abstract boolean isConnected();
+    
+    /**
+     * Returns the Instrument Manager.
+     *
+     * @return The Instrument Manager.
+     */
+    public abstract InstrumentManagerData getInstrumentManager();
+    
+    /**
+     * Causes the InstrumentManagerConnection to update itself with the latest
+     *  data from the server.  Called by the updateConnection method.
+     */
+    public void update()
     {
-        if ( getLogger().isDebugEnabled() )
-        {
-            getLogger().debug( "Attempt to open a new connection to " + m_host + ":" + m_port );
-        }
-
-        SocketCustomStreamHostContext hostContext =
-            new SocketCustomStreamHostContext.WithSimpleDefaults( m_host, m_port );
-
-        m_altrmiHostContext = hostContext;
-        m_altrmiFactory = new ClientSideClassFactory( hostContext, true );
-
-        if ( getLogger().isDebugEnabled() )
-        {
-            getLogger().debug("Connected.  Listing Published Altrmi Objects At Server...");
-        }
-
-        String[] listOfPublishedObjectsOnServer = m_altrmiFactory.list();
-        for ( int i = 0; i < listOfPublishedObjectsOnServer.length; i++ )
+        // If we are currently connected then we are only looking for changes so do the
+        //  regular update.  If not connected then we will want all of the data.
+        if ( isConnected() )
         {
-            getLogger().debug( "  [" + i + "]:" + listOfPublishedObjectsOnServer[i] );
+            getInstrumentManager().update();
         }
-
-        m_manager = (InstrumentManagerClient)m_altrmiFactory.lookup(
-            "InstrumentManagerClient" );
-
-        m_closed = false;
-
-        // Notify the listeners.
-        InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
-        for ( int i = 0; i < listenerArray.length; i++ )
+        else
         {
-            listenerArray[i].opened( this );
+            getInstrumentManager().updateAll();
         }
+        
+        String description = getInstrumentManager().getDescription();
+        if ( !m_descriptionLabel.getText().equals( description ) )
+        {
+            m_descriptionLabel.setText( description );
+        }
+        
+        getTreeModel().refreshModel();
+        
+        // Handle the leased samples.
+        handleLeasedSamples();
     }
 
     /**
-     * Attempts to open the connection.  If it fails, it just leaves it closed.
+     * Invokes GC on the JVM running the InstrumentManager.
      */
-    void tryOpen()
+    protected abstract void invokeGC();
+
+    /**
+     * Saves the current state into a Configuration.
+     *
+     * @return The state as a Configuration.
+     */
+    public Configuration saveState()
     {
-        try
-        {
-            open();
-        }
-        catch ( ConnectionRefusedException e )
-        {
-            getLogger().debug( "Connection refused.  Server not running?" );
-        }
-        catch ( ConnectionException e )
-        {
-            if ( getLogger().isDebugEnabled() )
-            {
-                getLogger().debug(
-                    "Unable to open connection.  Got an unexpected Altrmi exception.", e );
-            }
-        }
-        catch ( IOException e )
+        synchronized( this )
         {
-            if ( getLogger().isDebugEnabled() )
+            DefaultConfiguration state = new DefaultConfiguration( "connection", "-" );
+            
+            // Save any maintained samples
+            MaintainedSampleLease[] samples = getMaintainedSampleLeaseArray();
+            for ( int i = 0; i < samples.length; i++ )
             {
-                getLogger().debug(
-                    "Unable to open connection.  Got an unexpected IO exception.", e );
+                state.addChild( samples[ i ].saveState() );
             }
+            
+            return state;
         }
     }
 
     /**
-     * Returns true if the connection is currently closed.
+     * Loads the state from a Configuration object.
      *
-     * @return True if the connection is currently closed.
-     */
-    boolean isClosed()
-    {
-        return m_closed;
-    }
-
-    /**
-     * Closes the connection, but keeps it around.  If the remote instrument manager
-     *  is running the connection will reopen itself.
+     * @param state Configuration object to load state from.
+     *
+     * @throws ConfigurationException If there were any problems loading the
+     *                                state.
      */
-    void close()
+    public void loadState( Configuration state )
+        throws ConfigurationException
     {
-        getLogger().debug( "close()" );
-
-        if ( !m_closed )
+        synchronized( this )
         {
-            m_closed = true;
-            m_manager = null;
-            m_altrmiFactory.close();
-            m_altrmiFactory = null;
-            // Uncomment this when it gets implemented.
-            // m_altrmiHostContext.close();
-            m_altrmiHostContext = null;
-        }
+            // Load any maintained samples
+            Configuration[] sampleConfs = state.getChildren( "maintained-sample" );
+            for( int i = 0; i < sampleConfs.length; i++ )
+            {
+                Configuration sampleConf = sampleConfs[ i ];
+                String instrumentName = sampleConf.getAttribute( "instrument-name" );
+                int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType(
+                    sampleConf.getAttribute( "type" ) );
+                long sampleInterval = sampleConf.getAttributeAsLong( "interval" );
+                int sampleSize = sampleConf.getAttributeAsInteger( "size" );
+                long sampleLeaseDuration = sampleConf.getAttributeAsLong( "lease-duration" );
+                String sampleDescription = sampleConf.getAttribute( "description" );
 
-        // Notify the listeners.
-        InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
-        for ( int i = 0; i < listenerArray.length; i++ )
-        {
-            listenerArray[i].closed( this );
+                startMaintainingSample( instrumentName, sampleType, sampleInterval, sampleSize,
+                    sampleLeaseDuration, sampleDescription );
+            }
         }
     }
-
+    
     /**
-     * Returns true if the connection is currently deleted.
+     * Returns the TreeModel which contains the entire Instrument tree for
+     *  this connection.
      *
-     * @return True if the connection is currently deleted.
-     */
-    boolean isDeleted()
-    {
-        return m_deleted;
-    }
-
-    /**
-     * Called when the connection should be closed and then deleted along with
-     *  any frames and resources that are associated with it.
+     * @return The TreeModel.
      */
-    void delete()
+    InstrumentManagerTreeModel getTreeModel()
     {
-        getLogger().debug( "delete()" );
-        close();
-
-        m_deleted = true;
-
-        // Notify the listeners.
-        InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
-        for ( int i = 0; i < listenerArray.length; i++ )
-        {
-            listenerArray[i].deleted( this );
-        }
+        return m_treeModel;
     }
 
-    boolean ping()
+    DefaultMutableTreeNode getInstrumentSampleTreeNode( String sampleName )
     {
-        // Ping the server by requesting the manager's name
-        InstrumentManagerClient manager = m_manager;
-        if ( manager != null )
-        {
-            try
-            {
-                manager.getName();
-                return true;
-            }
-            catch ( InvocationException e )
-            {
-                getLogger().debug( "Ping Failed.", e );
-
-                // Socket was closed.
-                close();
-            }
-        }
-
-        return false;
+        return m_treeModel.getInstrumentSampleTreeNode( sampleName );
     }
 
     /**
@@ -575,6 +449,32 @@
     }
 
     /**
+     * Returns a snapshot of the specified sample.  If a snapshot can not
+     *  be returned for any reason, then return null.
+     *
+     * @param Returns a snapshot of the specified sample.
+     */
+    InstrumentSampleSnapshotData getSampleSnapshot( String sampleName )
+    {
+        DefaultMutableTreeNode sampleNode = getInstrumentSampleTreeNode( sampleName );
+        if ( sampleNode == null )
+        {
+            return null;
+        }
+
+        InstrumentSampleNodeData sampleNodeData =
+            (InstrumentSampleNodeData)sampleNode.getUserObject();
+        InstrumentSampleData sampleData = sampleNodeData.getData();
+        if ( sampleData == null )
+        {
+            return null;
+        }
+
+        // Request the actual snapshot.
+        return sampleData.getSnapshot();
+    }
+
+    /**
      * Returns a sample frame given a sample name.
      * Caller must synchronize on this connection before calling.
      *
@@ -604,70 +504,14 @@
     }
 
     /**
-     * Create a new Sample assigned to the specified instrument descriptor.
-     *
-     * @param instrumentDescriptor Instrument to add a sample to.
-     */
-    void instrumentCreateSample( final InstrumentDescriptor instrumentDescriptor )
-    {
-        //m_frame.instrumentCreateSample( this, instrumentDescriptor );
-
-        SwingUtilities.invokeLater( new Runnable()
-        {
-            public void run()
-            {
-                CreateSampleDialog dialog =
-                    new CreateSampleDialog( m_frame, instrumentDescriptor );
-
-                dialog.setSampleDescription( "Each Second" );
-                dialog.setInterval( 1000 );
-                dialog.setSampleCount( 600 );  // 10 minutes of history
-                dialog.setLeaseTime( 600 );
-                dialog.setMaintainLease( true );
-                dialog.show();
-
-                if ( dialog.getAction() == CreateSampleDialog.BUTTON_OK )
-                {
-                    getLogger().debug( "New Sample: desc=" + dialog.getSampleDescription() +
-                        ", interval=" + dialog.getInterval() + ", size=" + dialog.getSampleCount() +
-                        ", lease=" + dialog.getLeaseTime() + ", type=" + dialog.getSampleType() );
-
-                    // If the sample already exists on the server, then the existing one
-                    //  will be returned.
-                    instrumentDescriptor.createInstrumentSample(
-                            dialog.getSampleDescription(),
-                            dialog.getInterval(),
-                            dialog.getSampleCount(),
-                            dialog.getLeaseTime(),
-                            dialog.getSampleType() );
-
-                    // Update the model.
-                    m_treeModel.updateInstrument( instrumentDescriptor );
-
-                    InstrumentSampleNodeData sampleNodeData = startMaintainingSample(
-                        instrumentDescriptor.getName(), dialog.getSampleType(),
-                        dialog.getInterval(), dialog.getSampleCount(),
-                        dialog.getLeaseTime(), dialog.getSampleDescription() );
-
-                    // We should always have a NodeData for the sample, but it is
-                    //  possible that it could be null if there were errors, so
-                    //  be careful.
-                    if ( sampleNodeData != null )
-                    {
-                        // Show a frame for the new sample
-                        viewSample( sampleNodeData );
-                    }
-                }
-            }
-        } );
-    }
-
-    /**
      * Loads an InstrumentSampleFrame from a saved state.
      *
      * @param sampleFrameState Saved state of the frame to load.
+     *
+     * @throws ConfigurationException If there are any problems with the state.
      */
-    void loadSampleFrame( Configuration sampleFrameState ) throws ConfigurationException
+    void loadSampleFrame( Configuration sampleFrameState )
+        throws ConfigurationException
     {
         // Get the sample name
         String sampleName = sampleFrameState.getAttribute( "sample" );
@@ -690,21 +534,21 @@
             sampleFrame = new InstrumentSampleFrame( sampleFrameState, this, m_frame );
             addSampleFrame( sampleName, sampleFrame );
             sampleFrame.addToDesktop( m_frame.getDesktopPane() );
-            sampleFrame.show();
         }
+        sampleFrame.show();  // Outside of synchronization to avoid deadlocks.
     }
-
+    
     /**
      * Displays a frame for the given sample.
      *
-     * @param sampleNodeData Instrument sample to display.
+     * @param sampleName Name of the sample to display.
      */
-    void viewSample( InstrumentSampleNodeData sampleNodeData )
+    void viewSample( String sampleName )
     {
         InstrumentSampleFrame sampleFrame;
         synchronized( this )
         {
-            String sampleName = sampleNodeData.getName();
+            //String sampleName = sampleNodeData.getName();
             sampleFrame = getSampleFrame( sampleName );
             if ( sampleFrame == null )
             {
@@ -723,7 +567,11 @@
             {
                 sampleFrame.setIcon( false );
             }
-            catch ( PropertyVetoException e ) {}
+            catch ( PropertyVetoException e )
+            {
+                // Shouldn't happen.
+                getLogger().warn( "Unexpected error", e );
+            }
         }
 
         // Set the focus of the frame so that it is selected and on top.
@@ -733,10 +581,33 @@
         }
         catch ( PropertyVetoException e )
         {
-            // Shouldn't happen, but ignore if it does.
+            // Shouldn't happen.
+            getLogger().warn( "Unexpected error", e );
         }
+        
+        // Always update the sample immediately to make the app look responsive.
+        sampleFrame.update();
     }
 
+
+    /**
+     * Called when the connection should be closed and then deleted along with
+     *  any frames and resources that are associated with it.
+     */
+    void delete()
+    {
+        getLogger().debug( "delete()" );
+
+        m_deleted = true;
+
+        // Notify the listeners.
+        InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
+        for ( int i = 0; i < listenerArray.length; i++ )
+        {
+            listenerArray[i].deleted( this );
+        }
+    }
+    
     /**
      * Called when a Sample Frame is closed.
      */
@@ -753,17 +624,20 @@
      * Start maintaining the lease for an instrument sample which already
      *  exists.
      *
+     * @param instrumentName The full name of the instrument whose sample is
+     *                       to be created or updated.
+     * @param type The type of sample to be created.
+     * @param interval Sample interval of the new sample.
+     * @param size Number of samples in the new sample.
      * @param leaseDuration Length of the lease to maintain in milliseconds.
-     *
-     * @return The NodeData object of the sample.  May return null if the
-     *         NodeData has not yet been created.
+     * @param description Description to assign to the new sample.
      */
-    InstrumentSampleNodeData startMaintainingSample( String instrumentName,
-                                                     int    type,
-                                                     long   interval,
-                                                     int    size,
-                                                     long   leaseDuration,
-                                                     String description )
+    void startMaintainingSample( String instrumentName,
+                                 int    type,
+                                 long   interval,
+                                 int    size,
+                                 long   leaseDuration,
+                                 String description )
     {
         if ( getLogger().isDebugEnabled() )
         {
@@ -787,21 +661,15 @@
             DefaultMutableTreeNode sampleTreeNode =
                 m_treeModel.getInstrumentSampleTreeNode( sampleName );
 
-            InstrumentSampleNodeData sampleNodeData;
             if ( sampleTreeNode != null )
             {
-                sampleNodeData = (InstrumentSampleNodeData)sampleTreeNode.getUserObject();
+                InstrumentSampleNodeData sampleNodeData =
+                    (InstrumentSampleNodeData)sampleTreeNode.getUserObject();
 
                 sampleNodeData.setLeaseDuration( leaseDuration );
                 sampleNodeData.setDescription( description );
-                m_treeModel.updateInstrumentSample( sampleNodeData.getDescriptor(), sampleTreeNode );
+                m_treeModel.updateInstrumentSample( sampleNodeData.getData(), sampleTreeNode );
             }
-            else
-            {
-                sampleNodeData = null;
-            }
-
-            return sampleNodeData;
         }
     }
 
@@ -830,7 +698,7 @@
                     (InstrumentSampleNodeData)sampleTreeNode.getUserObject();
 
                 sampleNodeData.setLeaseDuration( 0 );
-                m_treeModel.updateInstrumentSample( sampleNodeData.getDescriptor(), sampleTreeNode );
+                m_treeModel.updateInstrumentSample( sampleNodeData.getData(), sampleTreeNode );
             }
         }
     }
@@ -852,122 +720,126 @@
     }
 
     /**
-     * Invokes GC on the JVM running the InstrumentManager.
+     * Returns a thread save array representation of the MaintainedSampleLeases.
+     *
+     * @return A thread save array representation of the MaintainedSampleLeases.
      */
-    protected void invokeGC()
+    private MaintainedSampleLease[] getMaintainedSampleLeaseArray()
     {
-        InstrumentManagerClient manager = getInstrumentManagerClient();
-        if ( manager != null )
+        MaintainedSampleLease[] array = m_maintainedSampleLeaseArray;
+        if ( array == null )
         {
-            try
-            {
-                manager.invokeGarbageCollection();
-            }
-            catch ( InvocationException e )
+            synchronized(this)
             {
-                getLogger().warn( "Error executing GC on " + getHost() + ":" +
-                    getPort() + ": " + e.getMessage() );
+                m_maintainedSampleLeaseArray =
+                    new MaintainedSampleLease[ m_maintainedSampleLeaseMap.size() ];
+                m_maintainedSampleLeaseMap.values().toArray( m_maintainedSampleLeaseArray );
+                array = m_maintainedSampleLeaseArray;
             }
         }
-    }
-
-    DefaultMutableTreeNode getInstrumentSampleTreeNode( String sampleName )
-    {
-        return m_treeModel.getInstrumentSampleTreeNode( sampleName );
+        return array;
     }
 
     /**
-     * Returns a snapshot of the specified sample.  If a snapshot can not
-     *  be returned for any reason, then return null.
-     *
-     * @param Returns a snapshot of the specified sample.
+     * Called once each second by the main worker thread of the client.  This
+     *  method is responsible for maintaining and expiring leased samples.
      */
-    InstrumentSampleSnapshot getInstrumentSampleSnapshot( String sampleName )
+    void handleLeasedSamples()
     {
-        DefaultMutableTreeNode sampleNode = getInstrumentSampleTreeNode( sampleName );
-        if ( sampleNode == null )
-        {
-            return null;
-        }
-
-        InstrumentSampleNodeData sampleNodeData =
-            (InstrumentSampleNodeData)sampleNode.getUserObject();
-        InstrumentSampleDescriptor sampleDescriptor = sampleNodeData.getDescriptor();
-        if ( sampleDescriptor == null )
-        {
-            return null;
-        }
-
-        // Request the actual snapshot.
-        try
-        {
-            return sampleDescriptor.getSnapshot();
-        }
-        catch ( InvocationException e )
-        {
-            return null;
-        }
-    }
+        // If we are not connected, then there is nothing to be done here.
 
-    /*---------------------------------------------------------------
-     * State Methods
-     *-------------------------------------------------------------*/
-    /**
-     * Saves the current state into a Configuration.
-     *
-     * @return The state as a Configuration.
-     */
-    public final Configuration saveState()
-    {
-        synchronized(this)
+        // Only renew leases once every 30 seconds.
+        long now = System.currentTimeMillis();
+        if ( now - m_lastLeaseRenewalTime > 30000 )
         {
-            DefaultConfiguration state = new DefaultConfiguration( "connection", "-" );
-            state.setAttribute( "host", m_host );
-            state.setAttribute( "port", Integer.toString( m_port ) );
-
-            // Save any maintained samples
-            MaintainedSampleLease[] samples = getMaintainedSampleLeaseArray();
-            for ( int i = 0; i < samples.length; i++ )
+            getLogger().debug( "Renew Leases:" );
+            MaintainedSampleLease[] leases = getMaintainedSampleLeaseArray();
+            for ( int i = 0; i < leases.length; i++ )
             {
-                state.addChild( samples[ i ].saveState() );
+                MaintainedSampleLease lease = leases[i];
+                getLogger().debug( " lease: " + lease.getSampleName() );
+                
+                // Regardless of whether the sample already exists or not, it is created
+                //  or extended the same way.
+                getInstrumentManager().createInstrumentSample( lease.getInstrumentName(),
+                    lease.getDescription(), lease.getInterval(), lease.getSize(),
+                    lease.getLeaseDuration(), lease.getType() );
             }
-            return state;
+
+            // Also, take this oportunity to update all of the leased samples in
+            //  the model.
+            m_treeModel.renewAllSampleLeases();
+
+            m_lastLeaseRenewalTime = now;
         }
-    }
 
+        // Now have the TreeModel purge any expired samples from the tree.
+        m_treeModel.purgeExpiredSamples();
+    }
+    
+    
     /**
-     * Loads the state from a Configuration object.
-     *
-     * @param state Configuration object to load state from.
+     * Create a new Sample assigned to the specified instrument data.
      *
-     * @throws ConfigurationException If there were any problems loading the
-     *                                state.
+     * @param instrumentData Instrument to add a sample to.
      */
-    public final void loadState( Configuration state ) throws ConfigurationException
+    void showCreateSampleDialog( final InstrumentData instrumentData )
     {
-        synchronized( this )
+        SwingUtilities.invokeLater( new Runnable()
         {
-            // Host and port will have already been set.
-
-            // Load any maintained samples
-            Configuration[] sampleConfs = state.getChildren( "maintained-sample" );
-            for( int i = 0; i < sampleConfs.length; i++ )
+            public void run()
             {
-                Configuration sampleConf = sampleConfs[ i ];
-                String instrumentName = sampleConf.getAttribute( "instrument-name" );
-                int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType(
-                    sampleConf.getAttribute( "type" ) );
-                long sampleInterval = sampleConf.getAttributeAsLong( "interval" );
-                int sampleSize = sampleConf.getAttributeAsInteger( "size" );
-                long sampleLeaseDuration = sampleConf.getAttributeAsLong( "lease-duration" );
-                String sampleDescription = sampleConf.getAttribute( "description" );
+                CreateSampleDialog dialog = new CreateSampleDialog(
+                    m_frame, instrumentData.getName(), instrumentData.getDescription(),
+                    instrumentData.getType()  );
+                dialog.show();
 
-                startMaintainingSample( instrumentName, sampleType, sampleInterval, sampleSize,
-                    sampleLeaseDuration, sampleDescription );
+                if ( dialog.getAction() == CreateSampleDialog.BUTTON_OK )
+                {
+                    String description = dialog.getSampleDescription();
+                    long interval = dialog.getInterval();
+                    int sampleCount = dialog.getSampleCount();
+                    long leaseTime = dialog.getLeaseTime();
+                    int type = dialog.getSampleType();
+                    boolean maintain = dialog.getMaintainLease();
+                    
+                    if ( getLogger().isDebugEnabled() )
+                    {
+                        getLogger().debug( "New Sample: desc=" + description
+                            + ", interval=" + interval
+                            + ", size=" + sampleCount
+                            + ", lease=" + leaseTime
+                            + ", type=" + type
+                            + ", maintain=" + maintain );
+                    }
+
+                    // If the sample already exists on the server, then the existing one
+                    //  will be returned.
+                    instrumentData.createInstrumentSample(
+                        description,
+                        interval,
+                        sampleCount,
+                        leaseTime,
+                        type );
+                    
+                    // Update the connection so the new sample will be loaded.
+                    //update();
+                    
+                    // If configured to do so, start maintaining the sample
+                    if ( maintain )
+                    {
+                        startMaintainingSample( instrumentData.getName(), type, interval,
+                            sampleCount, leaseTime, description );
+                    }
+                    
+                    // Figure out what the name of the new sample will be
+                    String sampleName = InstrumentSampleUtils.generateFullInstrumentSampleName(
+                        instrumentData.getName(), type, interval, sampleCount );
+                    
+                    // Display a sample frame.
+                    viewSample( sampleName );
+                }
             }
-        }
+        } );
     }
-}
-
-
-
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,62 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentManagerData
+    extends Data
+{
+    /**
+     * Returns the name.
+     *
+     * @return The name.
+     */
+    String getName();
+    
+    /**
+     * Gets a thread-safe snapshot of the instrumentable list.
+     *
+     * @return A thread-safe snapshot of the instrumentable list.
+     */
+    InstrumentableData[] getInstrumentables();
+    
+    /**
+     * Causes the the entire instrument tree to be updated in one call.  Very fast
+     *  when it is known that all or most data has changed.
+     *
+     * @return true if successful.
+     */
+    boolean updateAll();
+    
+    /**
+     * Requests that a sample be created or that its lease be updated.
+     *
+     * @param instrumentName The full name of the instrument whose sample is
+     *                       to be created or updated.
+     * @param description Description to assign to the new sample.
+     * @param interval Sample interval of the new sample.
+     * @param sampleCount Number of samples in the new sample.
+     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param sampleType The type of sample to be created.
+     */
+    void createInstrumentSample( String instrumentName,
+                                 String description,
+                                 long interval,
+                                 int sampleCount,
+                                 long leaseTime,
+                                 int sampleType );
+}

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerTreeModel.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerTreeModel.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerTreeModel.java	Tue Jul 27 10:37:36 2004
@@ -27,10 +27,6 @@
 import javax.swing.tree.TreePath;
 
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentableDescriptor;
 
 /**
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
@@ -41,11 +37,10 @@
 {
     private final InstrumentManagerConnection m_connection;
 
-    /** The last InstrumentManagerClient referenced.  Used to tell when it changes. */
-    private InstrumentManagerClient m_lastClient;
-
     /** The state version of the last client. */
     private int m_lastClientStateVersion;
+    
+    private boolean m_lastConnected = false;
 
     private DefaultMutableTreeNode m_root;
 
@@ -77,7 +72,7 @@
      */
     public void opened( InstrumentManagerConnection connection )
     {
-        //getLogger.debug("InstrumentManagerTreeModel.opened(" + connection + ")");
+        getLogger().debug( "InstrumentManagerTreeModel.opened(" + connection + ")" );
         refreshModel();
     }
 
@@ -89,7 +84,7 @@
      */
     public void closed( InstrumentManagerConnection connection )
     {
-        //getLogger.debug("InstrumentManagerTreeModel.closed(" + connection + ")");
+        getLogger().debug( "InstrumentManagerTreeModel.closed(" + connection + ")" );
         refreshModel();
     }
 
@@ -100,7 +95,7 @@
      */
     public void deleted( InstrumentManagerConnection connection )
     {
-        //getLogger.debug("InstrumentManagerTreeModel.deleted(" + connection + ")");
+        getLogger().debug( "InstrumentManagerTreeModel.deleted(" + connection + ")" );
         refreshModel();
     }
 
@@ -416,9 +411,9 @@
             // Extract the NodeData from the TreeNode
             InstrumentSampleNodeData sampleNodeData =
                 (InstrumentSampleNodeData)leasedSampleArray[i].getUserObject();
-            InstrumentSampleDescriptor sampleDescriptor = sampleNodeData.getDescriptor();
+            InstrumentSampleData sample = sampleNodeData.getData();
 
-            updateInstrumentSample( sampleDescriptor );
+            updateInstrumentSample( sample );
         }
     }
 
@@ -441,9 +436,9 @@
                 // Update the Instrument containing the sample.
                 DefaultMutableTreeNode instrumentTreeNode =
                     (DefaultMutableTreeNode)leasedSampleArray[i].getParent();
-                InstrumentDescriptor instrumentDescriptor =
-                    ((InstrumentNodeData)instrumentTreeNode.getUserObject()).getDescriptor();
-                updateInstrument( instrumentDescriptor, instrumentTreeNode, -1 /*Force update*/ );
+                InstrumentData instrumentData =
+                    ((InstrumentNodeData)instrumentTreeNode.getUserObject()).getData();
+                updateInstrument( instrumentData, instrumentTreeNode, -1 /*Force update*/ );
             }
         }
     }
@@ -456,63 +451,38 @@
     void refreshModel()
     {
         // Is the connection open or not?
-        InstrumentManagerClient client = m_connection.getInstrumentManagerClient();
-        if ( client == null )
+        if ( m_connection.isConnected() != m_lastConnected )
         {
-            if ( m_lastClient == null )
-            {
-                // Nothing to do
-            }
-            else
-            {
-                m_root.removeAllChildren();
-                m_elementMap.clear();
-                m_leasedSampleMap.clear();
-                m_leasedSampleArray = null;
-                m_lastClientStateVersion = -1;
-                fireTreeStructureChanged( new TreeModelEvent( this, m_root.getPath() ) );
-            }
+            m_root.removeAllChildren();
+            m_elementMap.clear();
+            m_leasedSampleMap.clear();
+            m_leasedSampleArray = null;
+            m_lastClientStateVersion = -1;
+            fireTreeStructureChanged( new TreeModelEvent( this, m_root.getPath() ) );
         }
-        else
+        
+        if ( m_connection.isConnected() )
         {
-            if ( client != m_lastClient )
-            {
-                // All data will change.
-                m_root.removeAllChildren();
-                m_elementMap.clear();
-                m_leasedSampleMap.clear();
-                m_leasedSampleArray = null;
-                m_lastClientStateVersion = -1;
-                fireTreeStructureChanged( new TreeModelEvent( this, new Object[] { m_root } ) );
-            }
-
             // Need to update the child nodes. (Root Instrumentables)
-            try
-            {
-                updateInstrumentModelClient( client, m_root, m_lastClientStateVersion );
-            }
-            catch ( org.apache.altrmi.client.InvocationException e )
-            {
-                System.out.println( "Error updating the Instrumentables on " +
-                    m_connection.getHost() + ":" + m_connection.getPort() + ": " +
-                    e.getMessage() );
-            }
+            updateInstrumentManagerData(
+                m_connection.getInstrumentManager(), m_root, m_lastClientStateVersion );
         }
-        m_lastClient = client;
+        
+        m_lastConnected = m_connection.isConnected();
     }
 
     /**
-     * Called to update the local view of the InstrumentManagerClient in the TreeeModel.
+     * Called to update the local view of the InstrumentManagerData in the TreeeModel.
      *
-     * @param client The InstrumentModelClient to use for the update.
+     * @param manager The InstrumentManagerData to use for the update.
      * @param roorTreeNode The TreeNode representing the client.
      * @param oldStateVersion The state version at the time of the last update.
      */
-    private void updateInstrumentModelClient( InstrumentManagerClient client,
+    private void updateInstrumentManagerData( InstrumentManagerData manager,
                                               DefaultMutableTreeNode rootTreeNode,
                                               int oldStateVersion )
     {
-        int stateVersion = client.getStateVersion();
+        int stateVersion = manager.getStateVersion();
         if ( stateVersion == oldStateVersion )
         {
             // Already up to date.
@@ -521,16 +491,16 @@
 
         if ( getLogger().isDebugEnabled() )
         {
-            getLogger().debug( "update client(" + client.getName() + ") "
+            getLogger().debug( "update manager(" + manager.getName() + ") "
                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
         }
 
         // The latest Instrumentables will be in the correct order.
-        InstrumentableDescriptor[] descriptors = client.getInstrumentableDescriptors();
+        InstrumentableData[] instrumentables = manager.getInstrumentables();
         int i;
-        for ( i = 0; i < descriptors.length; i++ )
+        for ( i = 0; i < instrumentables.length; i++ )
         {
-            InstrumentableDescriptor descriptor = descriptors[i];
+            InstrumentableData instrumentable = instrumentables[i];
             int oldInstrumentableStateVersion = -1;
             DefaultMutableTreeNode newChild = null;
             int childCount = rootTreeNode.getChildCount();
@@ -541,7 +511,7 @@
                     DefaultMutableTreeNode oldChild =
                         (DefaultMutableTreeNode)rootTreeNode.getChildAt( i );
                     cmp = ((InstrumentableNodeData)oldChild.getUserObject()).getDescription().
-                        compareTo( descriptor.getDescription() );
+                        compareTo( instrumentable.getDescription() );
                     if ( cmp == 0 )
                     {
                         // This is the same object.
@@ -562,7 +532,7 @@
                     {
                         // Need to insert a new node.
                         newChild = new DefaultMutableTreeNode(
-                            new InstrumentableNodeData( descriptor, m_connection ), true );
+                            new InstrumentableNodeData( instrumentable ), true );
                         rootTreeNode.insert( newChild, i );
                         fireTreeNodesInserted( new TreeModelEvent( this,
                             rootTreeNode.getPath(),new int[] { i }, new Object[] { newChild } ) );
@@ -588,7 +558,7 @@
             {
                 // Append the new descriptor
                 newChild = new DefaultMutableTreeNode(
-                    new InstrumentableNodeData( descriptor, m_connection ), true );
+                    new InstrumentableNodeData( instrumentable ), true );
                 rootTreeNode.insert( newChild, i );
                 fireTreeNodesInserted( new TreeModelEvent( this, rootTreeNode.getPath(),
                     new int[] { i }, new Object[] { newChild } ) );
@@ -598,7 +568,7 @@
                     getName(), newChild );
             }
 
-            updateInstrumentable( descriptor, newChild, oldInstrumentableStateVersion );
+            updateInstrumentable( instrumentable, newChild, oldInstrumentableStateVersion );
         }
         // Remove any remaining old nodes
         while ( i < rootTreeNode.getChildCount() )
@@ -618,17 +588,16 @@
     }
 
     /**
-     * @param instrumentableDescriptor The descriptor of the Instrumentable to
-     *                                 update.
+     * @param instrumentableData The Instrumentable to update.
      * @param instrumentableTreeNode The tree node of the Instrumentable to
      *                               update.
      * @param oldStateVersion The state version at the time of the last update.
      */
-    private void updateInstrumentable( InstrumentableDescriptor instrumentableDescriptor,
+    private void updateInstrumentable( InstrumentableData instrumentableData,
                                        DefaultMutableTreeNode instrumentableTreeNode,
                                        int oldStateVersion )
     {
-        int stateVersion = instrumentableDescriptor.getStateVersion();
+        int stateVersion = instrumentableData.getStateVersion();
         if ( stateVersion == oldStateVersion )
         {
             // Already up to date.
@@ -637,20 +606,19 @@
 
         if ( getLogger().isDebugEnabled() )
         {
-            getLogger().debug( "update instrumentable(" + instrumentableDescriptor.getName() + ") "
+            getLogger().debug( "update instrumentable(" + instrumentableData.getName() + ") "
                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
         }
 
         // The latest Instrumentables will be in the correct order.
-        InstrumentableDescriptor[] descriptors =
-            instrumentableDescriptor.getChildInstrumentableDescriptors();
-        //System.out.println("Model.updateInstumentable() " + instrumentableDescriptor.getName() + " " + descriptors.length);
+        InstrumentableData[] childInstrumentables = instrumentableData.getInstrumentables();
+        //System.out.println("Model.updateInstumentable() " + instrumentableData.getName() + " " + childInstrumentables.length);
         int i;
-        for ( i = 0; i < descriptors.length; i++ )
+        for ( i = 0; i < childInstrumentables.length; i++ )
         {
-            InstrumentableDescriptor descriptor = descriptors[i];
+            InstrumentableData childInstrumentable = childInstrumentables[i];
             int oldInstrumentableStateVersion = -1;
-            //System.out.println("  " + descriptor.getName() );
+            //System.out.println("  " + childInstrumentable.getName() );
             DefaultMutableTreeNode newChild = null;
             int childCount = instrumentableTreeNode.getChildCount();
             if ( i < childCount )
@@ -662,7 +630,7 @@
                     if ( oldChild.getUserObject() instanceof InstrumentableNodeData )
                     {
                         cmp = ((InstrumentableNodeData)oldChild.getUserObject()).getDescription().
-                            compareTo( descriptor.getDescription() );
+                            compareTo( childInstrumentable.getDescription() );
                     }
                     else
                     {
@@ -691,7 +659,7 @@
                     {
                         // Need to insert a new node.
                         newChild = new DefaultMutableTreeNode(
-                            new InstrumentableNodeData( descriptor, m_connection ), true );
+                            new InstrumentableNodeData( childInstrumentable ), true );
                         instrumentableTreeNode.insert( newChild, i );
                         fireTreeNodesInserted( new TreeModelEvent( this,
                             instrumentableTreeNode.getPath(),new int[] { i },
@@ -719,7 +687,7 @@
             {
                 // Append the new descriptor
                 newChild = new DefaultMutableTreeNode(
-                    new InstrumentableNodeData( descriptor, m_connection ), true );
+                    new InstrumentableNodeData( childInstrumentable ), true );
                 instrumentableTreeNode.insert( newChild, i );
                 fireTreeNodesInserted( new TreeModelEvent( this, instrumentableTreeNode.getPath(),
                     new int[] { i }, new Object[] { newChild } ) );
@@ -729,7 +697,7 @@
                     getName(), newChild );
             }
 
-            updateInstrumentable( descriptor, newChild, oldInstrumentableStateVersion );
+            updateInstrumentable( childInstrumentable, newChild, oldInstrumentableStateVersion );
         }
         // Remove any remaining old Instrumentable nodes
         while ( i < instrumentableTreeNode.getChildCount() )
@@ -754,13 +722,13 @@
 
 
         // The latest Instruments will be in the correct order.
-        InstrumentDescriptor[] instrumentDescriptors =
-            instrumentableDescriptor.getInstrumentDescriptors();
-        for ( i = descriptors.length; i < instrumentDescriptors.length + descriptors.length; i++ )
+        InstrumentData[] instruments =
+            instrumentableData.getInstruments();
+        for ( i = childInstrumentables.length; i < instruments.length + childInstrumentables.length; i++ )
         {
-            InstrumentDescriptor descriptor = instrumentDescriptors[i - descriptors.length];
+            InstrumentData instrument = instruments[i - childInstrumentables.length];
             int oldInstrumentStateVersion = -1;
-            //System.out.println("  " + descriptor.getName() );
+            //System.out.println("  " + instrument.getName() );
             DefaultMutableTreeNode newChild = null;
             int childCount = instrumentableTreeNode.getChildCount();
             if ( i < childCount )
@@ -772,7 +740,7 @@
                     if ( oldChild.getUserObject() instanceof InstrumentNodeData )
                     {
                         cmp = ((InstrumentNodeData)oldChild.getUserObject()).getDescription().
-                            compareTo( descriptor.getDescription() );
+                            compareTo( instrument.getDescription() );
                     }
                     else
                     {
@@ -800,7 +768,7 @@
                     {
                         // Need to insert a new node.
                         newChild = new DefaultMutableTreeNode(
-                            new InstrumentNodeData( descriptor, m_connection ), true );
+                            new InstrumentNodeData( instrument, m_connection ), true );
                         instrumentableTreeNode.insert( newChild, i );
                         fireTreeNodesInserted( new TreeModelEvent( this,
                             instrumentableTreeNode.getPath(),new int[] { i },
@@ -828,7 +796,7 @@
             {
                 // Append the new descriptor
                 newChild = new DefaultMutableTreeNode(
-                    new InstrumentNodeData( descriptor, m_connection ), true );
+                    new InstrumentNodeData( instrument, m_connection ), true );
                 instrumentableTreeNode.insert( newChild, i );
                 fireTreeNodesInserted( new TreeModelEvent( this, instrumentableTreeNode.getPath(),
                     new int[] { i }, new Object[] { newChild } ) );
@@ -838,7 +806,7 @@
                     getName(), newChild );
             }
 
-            updateInstrument( descriptor, newChild, oldInstrumentStateVersion );
+            updateInstrument( instrument, newChild, oldInstrumentStateVersion );
         }
         // Remove any remaining old Instrument nodes
         while ( i < instrumentableTreeNode.getChildCount() )
@@ -858,28 +826,28 @@
     }
 
     /**
-     * @param instrumentDescriptor The descriptor of the Instrument to update.
+     * @param instrumentData The Instrument to update.
      */
-    void updateInstrument( InstrumentDescriptor instrumentDescriptor )
+    void updateInstrument( InstrumentData instrumentData )
     {
         // Find the tree node.
         DefaultMutableTreeNode instrumentTreeNode =
-            getInstrumentTreeNode( instrumentDescriptor.getName() );
+            getInstrumentTreeNode( instrumentData.getName() );
         if ( instrumentTreeNode != null )
         {
-            updateInstrument( instrumentDescriptor, instrumentTreeNode, -1 /* Force update */ );
+            updateInstrument( instrumentData, instrumentTreeNode, -1 /* Force update */ );
         }
     }
 
     /**
-     * @param instrumentDescriptor The descriptor of the Instrument to update.
+     * @param instrumentData The Instrument to update.
      * @param instrumentTreeNode The tree node of the Instrument to update.
      */
-    void updateInstrument( InstrumentDescriptor instrumentDescriptor,
+    void updateInstrument( InstrumentData instrumentData,
                            DefaultMutableTreeNode instrumentTreeNode,
                            int oldStateVersion )
     {
-        int stateVersion = instrumentDescriptor.getStateVersion();
+        int stateVersion = instrumentData.getStateVersion();
         if ( stateVersion == oldStateVersion )
         {
             // Already up to date.
@@ -888,37 +856,30 @@
 
         if ( getLogger().isDebugEnabled() )
         {
-            getLogger().debug( "update instrument(" + instrumentDescriptor.getName() + ") "
+            getLogger().debug( "update instrument(" + instrumentData.getName() + ") "
                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
         }
 
         // The latest Instrument Samples will be in the correct order.
-        InstrumentSampleDescriptor[] descriptors =
-            instrumentDescriptor.getInstrumentSampleDescriptors();
+        InstrumentSampleData[] samples =
+            instrumentData.getInstrumentSamples();
         //System.out.println("Model.updateInstument() " + instrumentDescriptor.getName() + " " + descriptors.length);
         int i;
-        for ( i = 0; i < descriptors.length; i++ )
+        for ( i = 0; i < samples.length; i++ )
         {
-            InstrumentSampleDescriptor descriptor = descriptors[i];
-            //System.out.println("  " + descriptor.getName() );
+            InstrumentSampleData sample = samples[i];
+            //System.out.println("  " + sample.getName() );
             DefaultMutableTreeNode newChild = null;
             int childCount = instrumentTreeNode.getChildCount();
             if ( i < childCount )
             {
                 int cmp;
                 do {
+                    // Old child will always be a sample
                     DefaultMutableTreeNode oldChild =
                         (DefaultMutableTreeNode)instrumentTreeNode.getChildAt( i );
-                    if ( oldChild.getUserObject() instanceof InstrumentSampleNodeData )
-                    {
-                        cmp = ((InstrumentSampleNodeData)oldChild.getUserObject()).
-                            getDescription().compareTo( descriptor.getDescription() );
-                    }
-                    else
-                    {
-                        // Always put Instrumentables before any other nodes.
-                        cmp = 1;
-                    }
+                    cmp = ((InstrumentSampleNodeData)oldChild.getUserObject()).
+                        getDescription().compareTo( sample.getDescription() );
 
                     if ( cmp == 0 )
                     {
@@ -938,8 +899,8 @@
                     {
                         // Need to insert a new node.
                         newChild = new DefaultMutableTreeNode(
-                            new InstrumentSampleNodeData( instrumentDescriptor.getName(),
-                            descriptor, m_connection ), true );
+                            new InstrumentSampleNodeData( instrumentData.getName(),
+                            sample, m_connection ), true );
                         instrumentTreeNode.insert( newChild, i );
                         fireTreeNodesInserted( new TreeModelEvent( this,
                             instrumentTreeNode.getPath(),new int[] { i },
@@ -989,8 +950,8 @@
             {
                 // Append the new descriptor
                 newChild = new DefaultMutableTreeNode(
-                    new InstrumentSampleNodeData( instrumentDescriptor.getName(), descriptor,
-                    m_connection ), true );
+                    new InstrumentSampleNodeData( instrumentData.getName(), sample, m_connection ),
+                    true );
                 instrumentTreeNode.insert( newChild, i );
                 fireTreeNodesInserted( new TreeModelEvent( this, instrumentTreeNode.getPath(),
                     new int[] { i }, new Object[] { newChild } ) );
@@ -1021,10 +982,6 @@
             // Need to remove an old node.
             DefaultMutableTreeNode oldChild =
                 (DefaultMutableTreeNode)instrumentTreeNode.getChildAt( i );
-            if ( !( oldChild.getUserObject() instanceof InstrumentSampleNodeData ) )
-            {
-                break;
-            }
 
             instrumentTreeNode.remove( i );
             fireTreeNodesRemoved( new TreeModelEvent(
@@ -1045,26 +1002,24 @@
     }
 
     /**
-     * @param sampleDescriptor The descriptor of the Instrument Sample to
-     *                         update.
+     * @param sampleData The Instrument Sample to update.
      */
-    void updateInstrumentSample( InstrumentSampleDescriptor sampleDescriptor )
+    void updateInstrumentSample( InstrumentSampleData sampleData )
     {
         // Find the tree node.
         DefaultMutableTreeNode sampleTreeNode =
-            getInstrumentSampleTreeNode( sampleDescriptor.getName() );
+            getInstrumentSampleTreeNode( sampleData.getName() );
         if ( sampleTreeNode != null )
         {
-            updateInstrumentSample( sampleDescriptor, sampleTreeNode );
+            updateInstrumentSample( sampleData, sampleTreeNode );
         }
     }
 
     /**
-     * @param sampleDescriptor The descriptor of the Instrument Sample to
-     *                         update.
+     * @param sampleData The Instrument Sample to update.
      * @param sampleTreeNode The tree node of the Instrument Sample to update.
      */
-    void updateInstrumentSample( InstrumentSampleDescriptor sampleDescriptor,
+    void updateInstrumentSample( InstrumentSampleData sampleData,
                                  DefaultMutableTreeNode sampleTreeNode )
     {
         // An update here should always lead to an event being fired.

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentNodeData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentNodeData.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentNodeData.java	Tue Jul 27 10:37:36 2004
@@ -23,9 +23,6 @@
 import javax.swing.ImageIcon;
 import javax.swing.JMenuItem;
 
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
-
 /**
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
  */
@@ -60,7 +57,7 @@
      *   file but is no longer used. */
     private static final ImageIcon m_iconInstrumentValOld;
     
-    private InstrumentDescriptor m_descriptor;
+    private InstrumentData m_data;
     private InstrumentManagerConnection m_connection;
     
     private boolean m_configured;
@@ -96,10 +93,10 @@
     /*---------------------------------------------------------------
      * Constructors
      *-------------------------------------------------------------*/
-    InstrumentNodeData( InstrumentDescriptor descriptor,
+    InstrumentNodeData( InstrumentData data,
                         InstrumentManagerConnection connection )
     {
-        m_descriptor = descriptor;
+        m_data = data;
         m_connection = connection;
         
         update();
@@ -119,7 +116,7 @@
         ImageIcon icon;
         switch ( getType() )
         {
-        case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
+        case InstrumentData.INSTRUMENT_TYPE_COUNTER:
             if ( isConfigured() && isRegistered() )
             {
                 icon = m_iconInstrumentCtrRegConf;
@@ -138,7 +135,7 @@
             }
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
+        case InstrumentData.INSTRUMENT_TYPE_VALUE:
             if ( isConfigured() && isRegistered() )
             {
                 icon = m_iconInstrumentValRegConf;
@@ -175,7 +172,7 @@
         String text;
         switch ( getType() )
         {
-        case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
+        case InstrumentData.INSTRUMENT_TYPE_COUNTER:
             if ( isConfigured() && isRegistered() )
             {
                 text = "Registered and Configured Counter Instrument";
@@ -194,7 +191,7 @@
             }
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
+        case InstrumentData.INSTRUMENT_TYPE_VALUE:
             if ( isConfigured() && isRegistered() )
             {
                 text = "Registered and Configured Value Instrument";
@@ -235,7 +232,9 @@
         {
             public void actionPerformed( ActionEvent event )
             {
-                m_connection.instrumentCreateSample( InstrumentNodeData.this.getDescriptor() );
+                // Display a dialog to ask the user what new sample to create.
+                InstrumentData data = InstrumentNodeData.this.getData();
+                m_connection.showCreateSampleDialog( data );
             }
         };
         JMenuItem createSampleItem = new JMenuItem( createSampleAction );
@@ -248,9 +247,9 @@
     /*---------------------------------------------------------------
      * Methods
      *-------------------------------------------------------------*/
-    InstrumentDescriptor getDescriptor()
+    InstrumentData getData()
     {
-        return m_descriptor;
+        return m_data;
     }
     
     boolean isConfigured()
@@ -271,24 +270,23 @@
     boolean update()
     {
         boolean changed = false;
-        changed |= update( m_descriptor.getName(), m_descriptor.getDescription(),
-            m_descriptor.getStateVersion() );
+        changed |= update( m_data.getName(), m_data.getDescription(), m_data.getStateVersion() );
         
-        boolean newConfigured = m_descriptor.isConfigured();
+        boolean newConfigured = m_data.isConfigured();
         if ( newConfigured != m_configured )
         {
             changed = true;
             m_configured = newConfigured;
         }
         
-        boolean newRegistered = m_descriptor.isRegistered();
+        boolean newRegistered = m_data.isRegistered();
         if ( newRegistered != m_registered )
         {
             changed = true;
             m_registered = newRegistered;
         }
         
-        int newType = m_descriptor.getType();
+        int newType = m_data.getType();
         if ( newType != m_type )
         {
             changed = true;
@@ -297,5 +295,4 @@
         
         return changed;
     }
-
 }

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,34 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentSampleData
+    extends InstrumentSampleElementData
+{
+    /**
+     * Requests that the sample's lease be updated.
+     */
+    void updateLease();
+    
+    /**
+     * Returns a snapshot of the data in the sample.
+     *
+     * @return A snapshot of the sample.
+     */
+    InstrumentSampleSnapshotData getSnapshot();
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleElementData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleElementData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,93 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentSampleElementData
+    extends ElementData
+{
+    /** Type which identifies CounterInstrumentSamples. */
+    int INSTRUMENT_SAMPLE_TYPE_COUNTER = 101;
+    
+    /** Type which identifies MinimumInstrumentSamples. */
+    int INSTRUMENT_SAMPLE_TYPE_MINIMUM = 102;
+    
+    /** Type which identifies MaximumInstrumentSamples. */
+    int INSTRUMENT_SAMPLE_TYPE_MAXIMUM = 103;
+    
+    /** Type which identifies MeanInstrumentSamples. */
+    int INSTRUMENT_SAMPLE_TYPE_MEAN = 104;
+    
+    /**
+     * Returns the sample interval.  The period of each sample in millisends.
+     *
+     * @return The sample interval.
+     */
+    long getInterval();
+    
+    /**
+     * Returns the number of samples in the sample history.
+     *
+     * @return The size of the sample history.
+     */
+    int getSize();
+    
+    /**
+     * Returns the type of the Instrument Sample.  Possible values include
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_COUNTER,
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM,
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MEAN, or
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MINIMUM.
+     *
+     * @return The type of the Instrument Sample.
+     */
+    int getType();
+    
+    /**
+     * Obtain the value of the sample.  All samples are integers, so the profiled
+     * objects must measure quantity (numbers of items), rate (items/period), time in
+     * milliseconds, etc.
+     *
+     * @return The sample value.
+     */
+    int getValue();
+    
+    /**
+     * Obtain the UNIX time of the beginning of the sample.
+     *
+     * @return The UNIX time of the beginning of the sample.
+     */
+    long getTime();
+    
+    /**
+     * Obtain the UNIX time when the lease expires.
+     *
+     * @return The UNIX time when the lease expires.
+     */
+    long getLeaseExpirationTime();
+    
+    /**
+     * Returns the Type of the Instrument which can use the sample.  This
+     *  should be the same for all instances of a class.
+     * <p>
+     * Should be one of the following: InstrumentData.PROFILE_POINT_TYPE_COUNTER
+     *  or InstrumentData.PROFILE_POINT_TYPE_VALUE
+     *
+     * @return The Type of the Instrument which can use the sample.
+     */
+    int getInstrumentType();
+}
\ No newline at end of file

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java	Tue Jul 27 10:37:36 2004
@@ -29,7 +29,6 @@
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfiguration;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleSnapshot;
 
 /**
  *
@@ -112,8 +111,7 @@
     protected void getState( DefaultConfiguration stateConfig )
     {
         stateConfig.setAttribute( "type", FRAME_TYPE );
-        stateConfig.setAttribute( "host", m_connection.getHost() );
-        stateConfig.setAttribute( "port", Integer.toString( m_connection.getPort() ) );
+        stateConfig.setAttribute( "url", m_connection.getKey().toString() );
         stateConfig.setAttribute( "sample", m_instrumentSampleName );
     }
     
@@ -266,9 +264,9 @@
     /**
      * Initializes the chart
      *
-     * @param snapshot InstrumentSampleSnapshot to use to initialize the chart.
+     * @param snapshot InstrumentSampleSnapshotData to use to initialize the chart.
      */
-    private void initChart( InstrumentSampleSnapshot snapshot )
+    private void initChart( InstrumentSampleSnapshotData snapshot )
     {
         // Decide on a line interval based on the interval of the sample.
         long interval = snapshot.getInterval();
@@ -326,7 +324,7 @@
         getContentPane().add( m_lineChart );
     }
     
-    private void setStateSnapshot( InstrumentSampleSnapshot snapshot )
+    private void setStateSnapshot( InstrumentSampleSnapshotData snapshot )
     {
         if ( m_state != STATE_SNAPSHOT )
         {
@@ -420,36 +418,39 @@
      */
     void update()
     {
-        // Request a snapshot from the connection
-        InstrumentSampleSnapshot snapshot =
-            m_connection.getInstrumentSampleSnapshot( m_instrumentSampleName );
-        if ( snapshot == null )
+        if ( m_connection.isDeleted() )
         {
-            // A sample was not available.  Why.
-            if ( m_connection.isDeleted() )
-            {
-                // The connection was closed and deleted.
-                hideFrame();
-            }
-            if ( m_connection.isClosed() )
-            {
-                // Connection was closed.
-                setStateDisconnected();
-            }
-            else if ( ( m_state == STATE_SNAPSHOT ) || ( m_state == STATE_EXPIRED ) )
+            // The connection was closed and deleted.
+            hideFrame();
+        }
+        else
+        {
+            // Request a snapshot from the connection
+            InstrumentSampleSnapshotData snapshot =
+                m_connection.getSampleSnapshot( m_instrumentSampleName );
+            if ( snapshot == null )
             {
-                // We were getting snapshots, then they stopped.  The sample expired.
-                setStateSampleExpired();
+                // A sample was not available.  Why.
+                if ( !m_connection.isConnected() )
+                {
+                    // Connection was closed.
+                    setStateDisconnected();
+                }
+                else if ( ( m_state == STATE_SNAPSHOT ) || ( m_state == STATE_EXPIRED ) )
+                {
+                    // We were getting snapshots, then they stopped.  The sample expired.
+                    setStateSampleExpired();
+                }
+                else
+                {
+                    // Sample not found.
+                    setStateSampleMissing();
+                }
             }
             else
             {
-                // Sample not found.
-                setStateSampleMissing();
+                setStateSnapshot( snapshot );
             }
-        }
-        else
-        {
-            setStateSnapshot( snapshot );
         }
     }
 }

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleNodeData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleNodeData.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleNodeData.java	Tue Jul 27 10:37:36 2004
@@ -25,10 +25,6 @@
 import javax.swing.ImageIcon;
 import javax.swing.JMenuItem;
 
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleUtils;
-
 /**
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
  */
@@ -48,7 +44,7 @@
     private static final ImageIcon[][] m_icons = new ImageIcon[4][4];
     
     private String m_instrumentName;
-    private InstrumentSampleDescriptor m_descriptor;
+    private InstrumentSampleData m_data;
     private InstrumentManagerConnection m_connection;
     
     private boolean m_configured;
@@ -68,11 +64,6 @@
     /** Time interval of the sample points. */
     private long m_interval;
     
-    /** Sample Frame. */
-    /* Old
-    private InstrumentSampleFrame m_sampleFrame;
-    */
-    
     /*---------------------------------------------------------------
      * Class Initializer
      *-------------------------------------------------------------*/
@@ -89,16 +80,16 @@
     
     private static void loadTypeIcons( ClassLoader cl, int type, String prefix )
     {
-        m_icons[ type ][ ICON_SUBTYPE_CONF ] =
+        m_icons[type][ICON_SUBTYPE_CONF] =
             new ImageIcon( cl.getResource( prefix + "conf.gif") );
         
-        m_icons[ type ][ ICON_SUBTYPE_LEASE ] =
+        m_icons[type][ICON_SUBTYPE_LEASE] =
             new ImageIcon( cl.getResource( prefix + "lease.gif") );
         
-        m_icons[ type ][ ICON_SUBTYPE_MAINTAINED_LEASE ] =
+        m_icons[type][ICON_SUBTYPE_MAINTAINED_LEASE] =
             new ImageIcon( cl.getResource( prefix + "mlease.gif") );
         
-        m_icons[ type ][ ICON_SUBTYPE_OLD ] =
+        m_icons[type][ICON_SUBTYPE_OLD] =
             new ImageIcon( cl.getResource( prefix + "old.gif") );
     }
     
@@ -106,11 +97,11 @@
      * Constructors
      *-------------------------------------------------------------*/
     InstrumentSampleNodeData( String instrumentName,
-                              InstrumentSampleDescriptor descriptor,
+                              InstrumentSampleData data,
                               InstrumentManagerConnection connection )
     {
         m_instrumentName = instrumentName;
-        m_descriptor = descriptor;
+        m_data = data;
         m_connection = connection;
         
         update();
@@ -130,19 +121,19 @@
         int iconType;
         switch ( getType() )
         {
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_COUNTER:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_COUNTER:
             iconType = ICON_TYPE_CNT;
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
             iconType = ICON_TYPE_MAX;
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MEAN:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MEAN:
             iconType = ICON_TYPE_MEAN;
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
             iconType = ICON_TYPE_MIN;
             break;
             
@@ -172,7 +163,7 @@
             iconSubtype = ICON_SUBTYPE_OLD;
         }
         
-        return m_icons[ iconType ][ iconSubtype ];
+        return m_icons[iconType][iconSubtype];
     }
     
     /**
@@ -185,7 +176,7 @@
         String text;
         switch ( getType() )
         {
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_COUNTER:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_COUNTER:
             if ( isConfigured() )
             {
                 text = "Configured Counter Instrument Sample";
@@ -209,7 +200,7 @@
             }
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
             if ( isConfigured() )
             {
                 text = "Configured Maximum Value Instrument Sample";
@@ -233,7 +224,7 @@
             }
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MEAN:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MEAN:
             if ( isConfigured() )
             {
                 text = "Configured Mean Value Instrument Sample";
@@ -257,7 +248,7 @@
             }
             break;
             
-        case InstrumentManagerClient.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
+        case InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
             if ( isConfigured() )
             {
                 text = "Configured Minimum Value Instrument Sample";
@@ -303,7 +294,7 @@
         {
             public void actionPerformed( ActionEvent event )
             {
-                m_connection.viewSample( InstrumentSampleNodeData.this );
+                m_connection.viewSample( InstrumentSampleNodeData.this.getName() );
             }
         };
         JMenuItem viewItem = new JMenuItem( viewAction );
@@ -318,7 +309,8 @@
                 {
                     public void actionPerformed( ActionEvent event )
                     {
-                        m_connection.stopMaintainingSample( InstrumentSampleNodeData.this.getName() );
+                        m_connection.stopMaintainingSample(
+                            InstrumentSampleNodeData.this.getName() );
                     }
                 };
                 JMenuItem stopMaintainingItem = new JMenuItem( stopMaintainingAction );
@@ -333,9 +325,11 @@
                     {
                         // Need to show a dialog here.
                         long leaseDuration = 600000;
-                        String description = "Menu Generated: " + InstrumentSampleUtils.generateInstrumentSampleName( m_type, m_interval, m_size );
-                        
-                        m_connection.startMaintainingSample( m_instrumentName, m_type, m_interval, m_size, leaseDuration, description );
+                        String description = InstrumentSampleUtils.getDefaultDescriptionForType(
+                            m_type, m_interval );
+                        m_connection.startMaintainingSample(
+                            m_instrumentName, m_type, m_interval, m_size, leaseDuration,
+                            description );
                     }
                 };
                 JMenuItem startMaintainingItem = new JMenuItem( startMaintainingAction );
@@ -344,7 +338,7 @@
             }
         }
         
-        JMenuItem[] menuItemArray = new JMenuItem[ menuItems.size() ];
+        JMenuItem[] menuItemArray = new JMenuItem[menuItems.size()];
         menuItems.toArray( menuItemArray );
         
         return menuItemArray;
@@ -355,15 +349,15 @@
      */
     void select()
     {
-        m_connection.viewSample( this );
+        m_connection.viewSample( getName() );
     }
     
     /*---------------------------------------------------------------
      * Methods
      *-------------------------------------------------------------*/
-    InstrumentSampleDescriptor getDescriptor()
+    InstrumentSampleData getData()
     {
-        return m_descriptor;
+        return m_data;
     }
     
     boolean isConfigured()
@@ -399,38 +393,37 @@
     boolean update()
     {
         boolean changed = false;
-        changed |= update( m_descriptor.getName(), m_descriptor.getDescription(),
-            m_descriptor.getStateVersion() );
+        changed |= update( m_data.getName(), m_data.getDescription(), m_data.getStateVersion() );
         
-        boolean newConfigured = m_descriptor.isConfigured();
+        boolean newConfigured = m_data.isConfigured();
         if ( newConfigured != m_configured )
         {
             changed = true;
             m_configured = newConfigured;
         }
         
-        long newLeaseExpireTime = m_descriptor.getLeaseExpirationTime();
+        long newLeaseExpireTime = m_data.getLeaseExpirationTime();
         if ( newLeaseExpireTime != m_leaseExpireTime )
         {
             changed = true;
             m_leaseExpireTime = newLeaseExpireTime;
         }
         
-        int newType = m_descriptor.getType();
+        int newType = m_data.getType();
         if ( newType != m_type )
         {
             changed = true;
             m_type = newType;
         }
         
-        int newSize = m_descriptor.getSize();
+        int newSize = m_data.getSize();
         if ( newSize != m_size )
         {
             changed = true;
             m_size = newSize;
         }
         
-        long newInterval = m_descriptor.getInterval();
+        long newInterval = m_data.getInterval();
         if ( newInterval != m_interval )
         {
             changed = true;
@@ -471,16 +464,4 @@
     {
         return m_leaseDuration;
     }
-    
-    /* Old
-    void setInstrumentSampleFrame( InstrumentSampleFrame frame )
-    {
-        m_sampleFrame = frame;
-    }
-    
-    InstrumentSampleFrame getInstrumentSampleFrame()
-    {
-        return m_sampleFrame;
-    }
-    */
 }

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleSnapshotData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleSnapshotData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,29 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentSampleSnapshotData
+    extends InstrumentSampleElementData
+{
+    /**
+     * Returns an array of the individual values which make up the sample.
+     *
+     * @return An array of sample values.
+     */
+    int[] getSamples();
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleUtils.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleUtils.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,199 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * A series of methods which are useful when working with InstrumentSamples.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:19 $
+ * @since 4.1
+ */
+public class InstrumentSampleUtils
+{
+    /**
+     * Resolves an instrument sample type based on a name.
+     *
+     * @param type Type of the InstrumentSample to resolve.  Accepted values are:
+     *              "max", "maximum", "min", "minimum", "mean", 
+     *              "ctr", and "counter".
+     *
+     * @throws ConfigurationException if the specified sample type is unknown.
+     */
+    public static int resolveInstrumentSampleType( String type )
+        throws ConfigurationException {
+        
+        if ( type.equalsIgnoreCase( "max" ) || type.equalsIgnoreCase( "maximum" ) )
+        {
+            return InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM;
+        }
+        else if ( type.equalsIgnoreCase( "min" ) || type.equalsIgnoreCase( "minimum" ) )
+        {
+            return InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MINIMUM;
+        }
+        else if ( type.equalsIgnoreCase( "mean" ) )
+        {
+            return InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MEAN;
+        }
+        else if ( type.equalsIgnoreCase( "ctr" ) || type.equalsIgnoreCase( "counter" ) )
+        {
+            return InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER;
+        }
+        else
+        {
+            throw new ConfigurationException( "'" + type + "' is not a valid sample type." );
+        }
+    }
+    
+    public static String getInstrumentSampleTypeName( int type )
+    {
+        switch ( type )
+        {
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
+            return "maximum";
+            
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
+            return "minimum";
+        
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MEAN:
+            return "mean";
+            
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER:
+            return "counter";
+            
+        default:
+            return "unknown-" + type;
+        }
+    }
+    
+    /**
+     * Generates a sample name given its parameters.
+     *
+     * @param sampleType Type of the sample.
+     * @param sampleInterval Interval of the sample.
+     * @param sampleSize Size of the sample.
+     *
+     * @return A sample name.
+     */
+    public static String generateInstrumentSampleName( int sampleType,
+                                                       long sampleInterval,
+                                                       int sampleSize )
+    {
+        return getInstrumentSampleTypeName( sampleType ) + "_" + 
+            sampleInterval + "_" + sampleSize;
+    }
+    
+    /**
+     * Generates a fully qualified sample name given its parameters.
+     *
+     * @param instrumentName Name of the instrument which owns the sample.
+     * @param sampleType Type of the sample.
+     * @param sampleInterval Interval of the sample.
+     * @param sampleSize Size of the sample.
+     *
+     * @return A fully qualified sample name.
+     */
+    public static String generateFullInstrumentSampleName( String instrumentName,
+                                                           int sampleType,
+                                                           long sampleInterval,
+                                                           int sampleSize )
+    {
+        return instrumentName + "." +
+            generateInstrumentSampleName( sampleType, sampleInterval, sampleSize );
+    }
+    
+    /**
+     * Returns the default description for a given type.
+     *
+     * @param type Whose description is being requested.
+     * @param interval Interval of the Sample.
+     *
+     * @return The description.
+     */
+    public static String getDefaultDescriptionForType( int type, long interval )
+    {
+        StringBuffer sb = new StringBuffer();
+        switch ( type )
+        {
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_COUNTER:
+            sb.append( "Count each " );
+            break;
+            
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM:
+            sb.append( "Max Value each " );
+            break;
+            
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MEAN:
+            sb.append( "Mean Value each " );
+            break;
+            
+        case InstrumentSampleElementData.INSTRUMENT_SAMPLE_TYPE_MINIMUM:
+            sb.append( "Min Value each " );
+            break;
+            
+        default:
+            return "Unknown Type " + type;
+        }
+        
+        if ( interval == 1000 )
+        {
+            sb.append( "Second" );
+        }
+        else if ( interval == 60000 )
+        {
+            sb.append( "Minute" );
+        }
+        else if ( interval == 3600000 )
+        {
+            sb.append( "Hour" );
+        }
+        else if ( interval == 86400000 )
+        {
+            sb.append( "Day" );
+        }
+        else if ( interval % 86400000 == 0 )
+        {
+            sb.append( interval / 86400000 );
+            sb.append( " Days" );
+        }
+        else if ( interval % 3600000 == 0 )
+        {
+            sb.append( interval / 3600000 );
+            sb.append( " Hours" );
+        }
+        else if ( interval % 60000 == 0 )
+        {
+            sb.append( interval / 60000 );
+            sb.append( " Minutes" );
+        }
+        else if ( interval % 1000 == 0 )
+        {
+            sb.append( interval / 1000 );
+            sb.append( " Seconds" );
+        }
+        else
+        {
+            sb.append( interval );
+            sb.append( " Milliseconds" );
+        }
+        
+        return sb.toString();
+    }
+}

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,43 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client;
+
+public interface InstrumentableData
+    extends ElementData
+{
+    /**
+     * Returns the registered flag of the remote object.
+     *
+     * @return The registered flag of the remote object.
+     */
+    boolean isRegistered();
+    
+    /**
+     * Gets a thread-safe snapshot of the child instrumentable list.
+     *
+     * @return A thread-safe snapshot of the child instrumentable list.
+     */
+    InstrumentableData[] getInstrumentables();
+    
+    /**
+     * Gets a thread-safe snapshot of the instrument list.
+     *
+     * @return A thread-safe snapshot of the instrument list.
+     */
+    InstrumentData[] getInstruments();
+}

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableNodeData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableNodeData.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/InstrumentableNodeData.java	Tue Jul 27 10:37:36 2004
@@ -19,8 +19,6 @@
 
 import javax.swing.ImageIcon;
 
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentableDescriptor;
-
 /**
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
  */
@@ -41,8 +39,7 @@
      *   file but is no longer used. */
     private static final ImageIcon m_iconInstrumentableOld;
     
-    private InstrumentableDescriptor m_descriptor;
-    private InstrumentManagerConnection m_connection;
+    private InstrumentableData m_data;
     
     private boolean m_configured;
     private boolean m_registered;
@@ -67,11 +64,9 @@
     /*---------------------------------------------------------------
      * Constructors
      *-------------------------------------------------------------*/
-    InstrumentableNodeData( InstrumentableDescriptor descriptor,
-                            InstrumentManagerConnection connection )
+    InstrumentableNodeData( InstrumentableData data )
     {
-        m_descriptor = descriptor;
-        m_connection = connection;
+        m_data = data;
         
         update();
     }
@@ -138,9 +133,9 @@
     /*---------------------------------------------------------------
      * Methods
      *-------------------------------------------------------------*/
-    InstrumentableDescriptor getDescriptor()
+    InstrumentableData getData()
     {
-        return m_descriptor;
+        return m_data;
     }
     
     boolean isConfigured()
@@ -160,17 +155,16 @@
     boolean update()
     {
         boolean changed = false;
-        changed |= update( m_descriptor.getName(), m_descriptor.getDescription(),
-            m_descriptor.getStateVersion() );
+        changed |= update( m_data.getName(), m_data.getDescription(), m_data.getStateVersion() );
         
-        boolean newConfigured = m_descriptor.isConfigured();
+        boolean newConfigured = m_data.isConfigured();
         if ( newConfigured != m_configured )
         {
             changed = true;
             m_configured = newConfigured;
         }
         
-        boolean newRegistered = m_descriptor.isRegistered();
+        boolean newRegistered = m_data.isRegistered();
         if ( newRegistered != m_registered )
         {
             changed = true;
@@ -179,5 +173,4 @@
         
         return changed;
     }
-
 }

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Main.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Main.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/Main.java	Tue Jul 27 10:37:36 2004
@@ -93,6 +93,7 @@
         InstrumentClientFrame client = new InstrumentClientFrame( "Instrument Client" );
         int logLevel = ( debug ? ConsoleLogger.LEVEL_DEBUG : ConsoleLogger.LEVEL_INFO );
         client.enableLogging( new ConsoleLogger( logLevel ) );
+        client.initialize();
         client.setDefaultStateFile( defaultStateFile );
         client.show();
     }

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MaintainedSampleLease.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MaintainedSampleLease.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MaintainedSampleLease.java	Tue Jul 27 10:37:36 2004
@@ -20,7 +20,6 @@
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfiguration;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleUtils;
 
 /**
  *

Modified: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MenuBar.java
==============================================================================
--- excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MenuBar.java	(original)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/MenuBar.java	Tue Jul 27 10:37:36 2004
@@ -29,11 +29,6 @@
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleDescriptor;
-import org.apache.excalibur.instrument.manager.interfaces.InstrumentableDescriptor;
-
 /**
  *
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
@@ -44,7 +39,6 @@
     extends JMenuBar
 {
     protected InstrumentClientFrame m_frame;
-    //private ProfilerManager m_profilerManager;
 
     private JMenu m_menuFile;
 
@@ -58,14 +52,16 @@
     /*---------------------------------------------------------------
      * Constructors
      *-------------------------------------------------------------*/
-    MenuBar( InstrumentClientFrame frame/*, ProfilerManager profilerManager*/ )
+    MenuBar( InstrumentClientFrame frame )
     {
         m_frame = frame;
-        //m_profilerManager = profilerManager;
 
         add( buildFileMenu() );
         add( buildInstrumentManagerMenu() );
-        add( buildOptionsMenu() );
+        
+        // Build the options menu so its defaults are used, but don't use it for now.
+        buildOptionsMenu();
+        
         add( buildWindowMenu() );
     }
 
@@ -177,7 +173,7 @@
         return m_menuInstrumentManagers;
     }
 
-    protected void rebuildInstrumentManagersMenu()
+    private void rebuildInstrumentManagersMenu()
     {
         m_menuInstrumentManagers.removeAll();
 
@@ -196,7 +192,7 @@
         m_menuInstrumentManagers.add( connectItem );
 
         // Add links to the connections
-        InstrumentManagerConnection[] connections = m_frame.getInstrumentManagerConnections();
+        InstrumentManagerConnection[] connections = m_frame.getConnections();
         if ( connections.length > 0 )
         {
             m_menuInstrumentManagers.addSeparator();
@@ -242,8 +238,8 @@
         }
     }
 
-    protected void rebuildInstrumentManagerMenu( JMenu managerMenu,
-                                               InstrumentManagerConnection connection )
+    private void rebuildInstrumentManagerMenu( final JMenu managerMenu,
+                                               final InstrumentManagerConnection connection )
     {
         managerMenu.removeAll();
 
@@ -269,94 +265,22 @@
         deleteItem.setMnemonic( 'I' );
         managerMenu.add( deleteItem );
 
+        // Instrumentable menu items
+        InstrumentManagerData manager = connection.getInstrumentManager();
 
-        // Instrument menu items
-        try
+        if ( manager != null )
         {
-            InstrumentManagerClient manager = connection.getInstrumentManagerClient();
-
-            if ( manager != null )
-            {
-                managerMenu.addSeparator();
-
-                InstrumentableDescriptor[] descriptors = manager.getInstrumentableDescriptors();
-
-                for( int i = 0; i < descriptors.length; i++ )
-                {
-                    InstrumentableDescriptor descriptor = descriptors[ i ];
-
-                    if( showAll || descriptor.isConfigured() )
-                    {
-                        String description = descriptor.getDescription();
+            managerMenu.addSeparator();
 
-                        Action action = new AbstractAction( description )
-                        {
-                            public void actionPerformed( ActionEvent event )
-                            {
-                            }
-                        };
-                        action.putValue( "InstrumentManagerConnection", connection );
-                        action.putValue( "InstrumentableDescriptor", descriptor );
-
-                        JMenu menu = new LargeMenu( action );
-
-                        // Set up a Listener to handle the selected event.
-                        menu.addMenuListener( new MenuListener()
-                        {
-                            public void menuSelected( MenuEvent event )
-                            {
-                                JMenu menu = (JMenu)event.getSource();
-                                Action action = menu.getAction();
-
-                                rebuildInstrumentableMenu(
-                                    menu,
-                                    (InstrumentManagerConnection)action.getValue(
-                                        "InstrumentManagerConnection" ),
-                                    (InstrumentableDescriptor)action.getValue(
-                                        "InstrumentableDescriptor" ) );
-                            }
-
-                            public void menuDeselected( MenuEvent event )
-                            {
-                            }
-
-                            public void menuCanceled( MenuEvent event )
-                            {
-                            }
-                        } );
+            InstrumentableData[] instrumentables = manager.getInstrumentables();
 
-                        managerMenu.add( menu );
-                    }
-                }
-            }
-        }
-        catch ( org.apache.altrmi.client.InvocationException e )
-        {
-            // Something went wrong, so close the connection.
-            connection.close();
-        }
-    }
-
-    protected void rebuildInstrumentableMenu( JMenu instrumentableMenu,
-                                            InstrumentManagerConnection connection,
-                                            InstrumentableDescriptor instrumentableDescriptor )
-    {
-        instrumentableMenu.removeAll();
-
-        boolean showAll = m_menuItemShowUnconfigured.getState();
-
-        try
-        {
-            InstrumentDescriptor[] descriptors =
-                instrumentableDescriptor.getInstrumentDescriptors();
-
-            for( int i = 0; i < descriptors.length; i++ )
+            for( int i = 0; i < instrumentables.length; i++ )
             {
-                InstrumentDescriptor descriptor = descriptors[ i ];
+                InstrumentableData instrumentable = instrumentables[i];
 
-                if( showAll || descriptor.isConfigured() )
+                if( showAll || instrumentable.isConfigured() )
                 {
-                    String description = descriptor.getDescription();
+                    String description = instrumentable.getDescription();
 
                     Action action = new AbstractAction( description )
                     {
@@ -365,8 +289,7 @@
                         }
                     };
                     action.putValue( "InstrumentManagerConnection", connection );
-                    action.putValue( "InstrumentableDescriptor", instrumentableDescriptor );
-                    action.putValue( "InstrumentDescriptor", descriptor );
+                    action.putValue( "InstrumentableData", instrumentable );
 
                     JMenu menu = new LargeMenu( action );
 
@@ -378,14 +301,12 @@
                             JMenu menu = (JMenu)event.getSource();
                             Action action = menu.getAction();
 
-                            rebuildInstrumentMenu(
+                            rebuildInstrumentableMenu(
                                 menu,
                                 (InstrumentManagerConnection)action.getValue(
                                     "InstrumentManagerConnection" ),
-                                (InstrumentableDescriptor)action.getValue(
-                                    "InstrumentableDescriptor" ),
-                                (InstrumentDescriptor)action.getValue(
-                                    "InstrumentDescriptor" ) );
+                                (InstrumentableData)action.getValue(
+                                    "InstrumentableData" ) );
                         }
 
                         public void menuDeselected( MenuEvent event )
@@ -397,155 +318,183 @@
                         }
                     } );
 
-                    instrumentableMenu.add( menu );
+                    managerMenu.add( menu );
                 }
             }
         }
-        catch ( org.apache.altrmi.client.InvocationException e )
-        {
-            // Something went wrong, so close the connection.
-            connection.close();
-        }
     }
 
-    protected void rebuildInstrumentMenu( JMenu instrumentMenu,
-                                        InstrumentManagerConnection connection,
-                                        InstrumentableDescriptor instrumentableDescriptor,
-                                        InstrumentDescriptor instrumentDescriptor )
+    private void rebuildInstrumentableMenu( final JMenu instrumentableMenu,
+                                            final InstrumentManagerConnection connection,
+                                            final InstrumentableData instrumentable )
     {
-        instrumentMenu.removeAll();
+        instrumentableMenu.removeAll();
 
         boolean showAll = m_menuItemShowUnconfigured.getState();
+        
+        // Child Instrumentables
+        InstrumentableData[] children = instrumentable.getInstrumentables();
 
-        // Create Sample
-        Action createAction = new AbstractAction( "Create Sample..." )
+        for( int i = 0; i < children.length; i++ )
         {
-            public void actionPerformed( ActionEvent event )
+            InstrumentableData child = children[i];
+
+            if( showAll || child.isConfigured() )
             {
-                /*  Not implemented.
+                String description = child.getDescription();
 
-                JMenuItem item = (JMenuItem)event.getSource();
-                Action action = item.getAction();
+                Action action = new AbstractAction( description )
+                {
+                    public void actionPerformed( ActionEvent event )
+                    {
+                    }
+                };
+                action.putValue( "InstrumentManagerConnection", connection );
+                action.putValue( "InstrumentableData", child );
 
-                m_frame.instrumentCreateSample(
-                    (InstrumentManagerConnection)action.getValue( "InstrumentManagerConnection" ),
-                    (InstrumentDescriptor)action.getValue( "InstrumentDescriptor" ) );
-                */
-            }
-        };
-        createAction.putValue( "InstrumentManagerConnection", connection );
-        createAction.putValue( "InstrumentableDescriptor", instrumentableDescriptor );
-        createAction.putValue( "InstrumentDescriptor", instrumentDescriptor );
+                JMenu menu = new LargeMenu( action );
 
-        JMenuItem createItem = new JMenuItem( createAction );
-        createItem.setMnemonic( 'C' );
-        instrumentMenu.add( createItem );
+                // Set up a Listener to handle the selected event.
+                menu.addMenuListener( new MenuListener()
+                {
+                    public void menuSelected( MenuEvent event )
+                    {
+                        JMenu menu = (JMenu)event.getSource();
+                        Action action = menu.getAction();
+
+                        rebuildInstrumentableMenu(
+                            menu,
+                            (InstrumentManagerConnection)action.getValue(
+                                "InstrumentManagerConnection" ),
+                            (InstrumentableData)action.getValue(
+                                "InstrumentableData" ) );
+                    }
 
-        try
+                    public void menuDeselected( MenuEvent event )
+                    {
+                    }
+
+                    public void menuCanceled( MenuEvent event )
+                    {
+                    }
+                } );
+
+                instrumentableMenu.add( menu );
+            }
+        }
+        
+        // Instruments
+        InstrumentData[] instruments = instrumentable.getInstruments();
+
+        for( int i = 0; i < instruments.length; i++ )
         {
-            InstrumentSampleDescriptor[] descriptors =
-                instrumentDescriptor.getInstrumentSampleDescriptors();
+            InstrumentData instrument = instruments[ i ];
 
-            if ( descriptors.length > 0 )
+            if( showAll || instrument.isConfigured() )
             {
-                instrumentMenu.addSeparator();
+                String description = instrument.getDescription();
 
-                for( int i = 0; i < descriptors.length; i++ )
+                Action action = new AbstractAction( description )
                 {
-                    InstrumentSampleDescriptor descriptor = descriptors[ i ];
+                    public void actionPerformed( ActionEvent event )
+                    {
+                    }
+                };
+                action.putValue( "InstrumentManagerConnection", connection );
+                action.putValue( "InstrumentableData", instrumentable );
+                action.putValue( "InstrumentData", instrument );
+
+                JMenu menu = new LargeMenu( action );
 
-                    if( showAll || descriptor.isConfigured() )
+                // Set up a Listener to handle the selected event.
+                menu.addMenuListener( new MenuListener()
+                {
+                    public void menuSelected( MenuEvent event )
                     {
-                        String description = descriptor.getDescription();
+                        JMenu menu = (JMenu)event.getSource();
+                        Action action = menu.getAction();
 
-                        Action action = new AbstractAction( description )
-                        {
-                            public void actionPerformed( ActionEvent event )
-                            {
-                                /* Not implemented
-
-                                JMenuItem menu = (JMenuItem)event.getSource();
-                                Action action = menu.getAction();
-
-                                m_frame.openInstrumentSampleFrame(
-                                    (InstrumentManagerConnection)action.getValue(
-                                        "InstrumentManagerConnection" ),
-                                    (InstrumentSampleDescriptor)action.getValue(
-                                        "InstrumentSampleDescriptor" ) );
-                                */
-                            }
-                        };
-                        action.putValue( "InstrumentManagerConnection", connection );
-                        action.putValue( "InstrumentSampleDescriptor", descriptor );
+                        rebuildInstrumentMenu(
+                            menu,
+                            (InstrumentManagerConnection)action.getValue(
+                                "InstrumentManagerConnection" ),
+                            (InstrumentableData)action.getValue(
+                                "InstrumentableData" ),
+                            (InstrumentData)action.getValue(
+                                "InstrumentData" ) );
+                    }
 
-                        JMenuItem item = new JMenuItem( action );
+                    public void menuDeselected( MenuEvent event )
+                    {
+                    }
 
-                        instrumentMenu.add( item );
+                    public void menuCanceled( MenuEvent event )
+                    {
                     }
-                }
+                } );
+
+                instrumentableMenu.add( menu );
             }
         }
-        catch ( org.apache.altrmi.client.InvocationException e )
-        {
-            // Something went wrong, so close the connection.
-            connection.close();
-        }
     }
 
-    /*
-    private void rebuildProfilePointMenu( JMenu profilePointMenu,
-                                          ProfilableDescriptor profilableDescriptor,
-                                          ProfilePointDescriptor profilePointDescriptor )
+    private void rebuildInstrumentMenu( final JMenu instrumentMenu,
+                                        final InstrumentManagerConnection connection,
+                                        final InstrumentableData instrumentable,
+                                        final InstrumentData instrument )
     {
-        profilePointMenu.removeAll();
+        instrumentMenu.removeAll();
 
-        ProfileSampleDescriptor[] profileSampleDescriptors = profilePointDescriptor.getProfileSampleDescriptors();
+        boolean showAll = m_menuItemShowUnconfigured.getState();
 
-        Comparator comp = new Comparator()
+        // Create Sample
+        Action createAction = new AbstractAction( "Create Sample..." )
         {
-            public int compare( Object o1, Object o2 )
-            {
-                return ( (ProfileSampleDescriptor)o1 ).getDescription().
-                    compareTo( ( (ProfileSampleDescriptor)o2 ).getDescription() );
-            }
-
-            public boolean equals( Object obj )
+            public void actionPerformed( ActionEvent event )
             {
-                return false;
+                connection.showCreateSampleDialog( instrument );
             }
         };
-        Arrays.sort( profileSampleDescriptors, comp );
+        createAction.putValue( "InstrumentManagerConnection", connection );
+        createAction.putValue( "InstrumentableData", instrumentable );
+        createAction.putValue( "InstrumentData", instrument );
 
-        for( int i = 0; i < profileSampleDescriptors.length; i++ )
-        {
-            ProfileSampleDescriptor profileSampleDescriptor = profileSampleDescriptors[ i ];
+        JMenuItem createItem = new JMenuItem( createAction );
+        createItem.setMnemonic( 'C' );
+        instrumentMenu.add( createItem );
+
+        InstrumentSampleData[] samples = instrument.getInstrumentSamples();
 
-            String profileSampleName = profileSampleDescriptor.getDescription();
+        if ( samples.length > 0 )
+        {
+            instrumentMenu.addSeparator();
 
-            Action action = new AbstractAction( profileSampleName )
+            for( int i = 0; i < samples.length; i++ )
             {
-                public void actionPerformed( ActionEvent event )
+                final InstrumentSampleData sample = samples[ i ];
+
+                if( showAll || sample.isConfigured() )
                 {
-                    JMenuItem menu = (JMenuItem)event.getSource();
-                    Action action = menu.getAction();
+                    String description = sample.getDescription();
 
-                    m_frame.openProfileSampleFrame(
-                        (ProfilableDescriptor)action.getValue( "profilableDescriptor" ),
-                        (ProfilePointDescriptor)action.getValue( "profilePointDescriptor" ),
-                        (ProfileSampleDescriptor)action.getValue( "profileSampleDescriptor" ) );
-                }
-            };
-            action.putValue( "profilableDescriptor", profilableDescriptor );
-            action.putValue( "profilePointDescriptor", profilePointDescriptor );
-            action.putValue( "profileSampleDescriptor", profileSampleDescriptor );
+                    Action action = new AbstractAction( description )
+                    {
+                        public void actionPerformed( ActionEvent event )
+                        {
+                            connection.viewSample( sample.getName() );
+                        }
+                    };
+                    action.putValue( "InstrumentManagerConnection", connection );
+                    action.putValue( "InstrumentSampleData", sample );
 
-            JMenuItem item = new JMenuItem( action );
+                    JMenuItem item = new JMenuItem( action );
 
-            profilePointMenu.add( item );
+                    instrumentMenu.add( item );
+                }
+            }
         }
     }
-    */
-
+    
     private JMenu buildOptionsMenu()
     {
         m_menuOptions = new LargeMenu( "Options" );
@@ -553,7 +502,7 @@
 
         // Show Unconfigured Profilables option
         m_menuItemShowUnconfigured =
-            new JCheckBoxMenuItem( "Show Unconfigured Profilables", false );
+            new JCheckBoxMenuItem( "Show Unconfigured Instruments", true );
         m_menuOptions.add( m_menuItemShowUnconfigured );
 
         return m_menuOptions;

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,128 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import org.apache.excalibur.instrument.client.Data;
+import org.apache.excalibur.instrument.client.InstrumentManagerConnection;
+
+/**
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
+ * @since 4.1
+ */
+abstract class AbstractHTTPData
+    extends AbstractLogEnabled
+    implements Data
+{
+    /* Reference to the connection. */
+    private HTTPInstrumentManagerConnection m_connection;
+    
+    /* Description of the remote object. */
+    private String m_description;
+    
+    /** The current state version of the remote object. */
+    private int m_stateVersion;
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new AbstractHTTPData.
+     *
+     * @param description An initial description.
+     */
+    protected AbstractHTTPData( HTTPInstrumentManagerConnection connection,
+                                String description )
+    {
+        m_connection = connection;
+        m_description = description;
+        m_stateVersion = -1;
+    }
+    
+    /*---------------------------------------------------------------
+     * Data Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the InstrumentManagerConnection that owns the data object.
+     *
+     * @return The InstrumentManagerConnection that owns the data object.
+     */
+    public InstrumentManagerConnection getConnection()
+    {
+        return m_connection;
+    }
+    
+    /**
+     * Returns the description.
+     *
+     * @return The description.
+     */
+    public String getDescription()
+    {
+        return m_description;
+    }
+    
+    /**
+     * Returns the state version.
+     *
+     * @return The state version.
+     */
+    public int getStateVersion()
+    {
+        return m_stateVersion;
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration )
+        throws ConfigurationException
+    {
+        m_description = configuration.getAttribute( "description" );
+        m_stateVersion = configuration.getAttributeAsInteger( "state-version" );
+    }
+    
+    protected String urlEncode( String val )
+    {
+        try
+        {
+            return URLEncoder.encode( val, "UTF8" );
+        }
+        catch ( UnsupportedEncodingException e )
+        {
+            // Should never happen.
+            getLogger().error( "Bad encoding.", e );
+            return val;
+        }
+    }
+}

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,136 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import org.apache.excalibur.instrument.client.Data;
+import org.apache.excalibur.instrument.client.ElementData;
+
+/**
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
+ * @since 4.1
+ */
+abstract class AbstractHTTPElementData
+    extends AbstractHTTPData
+    implements ElementData
+{
+    /* The parent data object, or null for the root. */
+    private AbstractHTTPData m_parent;
+    
+    /* The name of the data object. */
+    private String m_name;
+    
+    /* Name of the configured flag of the remote object. */
+    private boolean m_configured;
+    
+    /*---------------------------------------------------------------
+     * Static Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the last element of a name separated by '.'s
+     */
+    protected static String lastNameToken( String name )
+    {
+        int pos = name.lastIndexOf( '.' );
+        if ( pos >= 0 )
+        {
+            return name.substring( pos + 1 );
+        }
+        else
+        {
+            return name;
+        }
+    }
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new AbstractHTTPElementData.
+     *
+     * @param description An initial description.
+     */
+    protected AbstractHTTPElementData( HTTPInstrumentManagerConnection connection,
+                                       AbstractHTTPData parent,
+                                       String name )
+    {
+        super( connection, lastNameToken( name ) );
+        m_parent = parent;
+        m_name = name;
+        m_configured = false;
+    }
+    
+    /*---------------------------------------------------------------
+     * HTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the parent data object.
+     *
+     * @return The parent data object.
+     */
+    public Data getParent()
+    {
+        return m_parent;
+    }
+    
+    /**
+     * Returns the name.
+     *
+     * @return The name.
+     */
+    public String getName()
+    {
+        return m_name;
+    }
+    
+    /**
+     * Returns the configured flag of the remote object.
+     *
+     * @return The configured flag of the remote object.
+     */
+    public boolean isConfigured()
+    {
+        return m_configured;
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        m_configured = configuration.getAttributeAsBoolean( "configured" );
+    }
+}

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,169 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import org.apache.excalibur.instrument.client.InstrumentSampleElementData;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+abstract class AbstractHTTPInstrumentSampleElementData
+    extends AbstractHTTPElementData
+    implements InstrumentSampleElementData
+{
+    /** The sample interval. */
+    private long m_interval;
+    
+    /** The size of the sample history. */
+    private int m_size;
+    
+    /** The type of the Instrument Sample. */
+    private int m_type;
+    
+    /** The sample value. */
+    private int m_value;
+    
+    /** The UNIX time of the beginning of the sample. */
+    private long m_time;
+    
+    /** The UNIX time when the lease expires. */
+    private long m_leaseExpirationTime;
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new AbstractHTTPInstrumentSampleElementData.
+     */
+    AbstractHTTPInstrumentSampleElementData( HTTPInstrumentManagerConnection connection,
+                                             AbstractHTTPData parent,
+                                             String name )
+    {
+        super( connection, parent, name );
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        m_interval = configuration.getAttributeAsLong( "interval" );
+        m_size = configuration.getAttributeAsInteger( "size" );
+        m_type = configuration.getAttributeAsInteger( "type" );
+        m_value = configuration.getAttributeAsInteger( "value" );
+        m_time = configuration.getAttributeAsLong( "time" );
+        m_leaseExpirationTime = configuration.getAttributeAsLong( "expiration-time" );
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentSampleElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the sample interval.  The period of each sample in millisends.
+     *
+     * @return The sample interval.
+     */
+    public long getInterval()
+    {
+        return m_interval;
+    }
+    
+    /**
+     * Returns the number of samples in the sample history.
+     *
+     * @return The size of the sample history.
+     */
+    public int getSize()
+    {
+        return m_size;
+    }
+    
+    /**
+     * Returns the type of the Instrument Sample.  Possible values include
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_COUNTER,
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MAXIMUM,
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MEAN, or
+     *  InstrumentSampleData.INSTRUMENT_SAMPLE_TYPE_MINIMUM.
+     *
+     * @return The type of the Instrument Sample.
+     */
+    public int getType()
+    {
+        return m_type;
+    }
+    
+    /**
+     * Obtain the value of the sample.  All samples are integers, so the profiled
+     * objects must measure quantity (numbers of items), rate (items/period), time in
+     * milliseconds, etc.
+     *
+     * @return The sample value.
+     */
+    public int getValue()
+    {
+        return m_value;
+    }
+    
+    /**
+     * Obtain the UNIX time of the beginning of the sample.
+     *
+     * @return The UNIX time of the beginning of the sample.
+     */
+    public long getTime()
+    {
+        return m_time;
+    }
+    
+    /**
+     * Obtain the UNIX time when the lease expires.
+     *
+     * @return The UNIX time when the lease expires.
+     */
+    public long getLeaseExpirationTime()
+    {
+        return m_leaseExpirationTime;
+    }
+    
+    /**
+     * Returns the Type of the Instrument which can use the sample.  This
+     *  should be the same for all instances of a class.
+     * <p>
+     * Should be one of the following: InstrumentData.PROFILE_POINT_TYPE_COUNTER
+     *  or InstrumentData.PROFILE_POINT_TYPE_VALUE
+     *
+     * @return The Type of the Instrument which can use the sample.
+     */
+    public int getInstrumentType()
+    {
+        return ((HTTPInstrumentData)getParent()).getType();
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,250 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.excalibur.instrument.client.InstrumentData;
+import org.apache.excalibur.instrument.client.InstrumentSampleData;
+
+class HTTPInstrumentData
+    extends AbstractHTTPElementData
+    implements InstrumentData
+{
+    /* The registered flag of the remote object. */
+    private boolean m_registered;
+    
+    /** The type of the Instrument. */
+    private int m_type;
+    
+    private List m_samples = new ArrayList();
+    private HTTPInstrumentSampleData[] m_sampleAry;
+    private Map m_sampleMap = new HashMap();
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentData.
+     */
+    HTTPInstrumentData( HTTPInstrumentableData parent,
+                        String name )
+    {
+        super( (HTTPInstrumentManagerConnection)parent.getConnection(), parent, name );
+        
+        m_registered = false;
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     * @param recurse True if state should be ignored and we should drill down
+     *                using data in this configuration.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration, boolean recurse )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug(
+                "Updated Instrument '" + getName() + "' to version " + getStateVersion() );
+        }
+        
+        m_registered = configuration.getAttributeAsBoolean( "registered" );
+        m_type = configuration.getAttributeAsInteger( "type" );
+        
+        // Samples can be added as well as removed for each update.  Build up a list of
+        //  old samples and remove each one that still exists on the server.  Any left
+        //  over have expired and must be removed.
+        Map oldSampleMap;
+        synchronized( m_samples )
+        {
+            oldSampleMap = new HashMap( m_sampleMap );
+        }
+        
+        Configuration[] sampleConfs = configuration.getChildren( "sample" );
+        for ( int i = 0; i < sampleConfs.length; i++ )
+        {
+            Configuration sConf = sampleConfs[i];
+            String sName = sConf.getAttribute( "name" );
+            int sStateVersion = sConf.getAttributeAsInteger( "state-version" );
+            
+            HTTPInstrumentSampleData sData;
+            synchronized( m_samples )
+            {
+                sData = (HTTPInstrumentSampleData)m_sampleMap.get( sName );
+                if ( sData == null )
+                {
+                    // It is new.
+                    sData = new HTTPInstrumentSampleData( this, sName );
+                    sData.enableLogging( getLogger().getChildLogger( sName ) );
+                    m_samples.add( sData );
+                    m_sampleMap.put( sName, sData );
+                    m_sampleAry = null;
+                }
+                oldSampleMap.remove( sName );
+            }
+            
+            if ( recurse )
+            {
+                sData.update( sConf );
+            }
+            else
+            {
+                if ( sStateVersion != sData.getStateVersion() )
+                {
+                    // Needs to be updated.
+                    sData.update();
+                }
+            }
+        }
+        
+        // Purge any old samples.
+        if ( !oldSampleMap.isEmpty() )
+        {
+            synchronized( m_samples )
+            {
+                for ( Iterator iter = oldSampleMap.values().iterator(); iter.hasNext(); )
+                {
+                    HTTPInstrumentSampleData sample = (HTTPInstrumentSampleData)iter.next();
+                    m_samples.remove( sample );
+                    m_sampleMap.remove( sample.getName() );
+                    m_sampleAry = null;
+                }
+            }
+        }
+    }
+    
+    /**
+     * Causes the InstrumentData to update itself with the latest data from
+     *  the server.
+     *
+     * @return true if successful.
+     */
+    public boolean update()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration = connection.getState(
+            "instrument.xml?packed=true&name=" + urlEncode( getName() ) );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration, false );
+                
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        
+        return false;
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the registered flag of the remote object.
+     *
+     * @return The registered flag of the remote object.
+     */
+    public boolean isRegistered()
+    {
+        return m_registered;
+    }
+    
+    /**
+     * Returns the type of the Instrument.  Possible values include
+     *  InstrumentData.INSTRUMENT_TYPE_COUNTER,
+     *  InstrumentData.INSTRUMENT_TYPE_VALUE or
+     *  InstrumentData.INSTRUMENT_TYPE_NONE, if the type was never set.
+     *
+     * @return The type of the Instrument.
+     */
+    public int getType()
+    {
+        return m_type;
+    }
+    
+    /**
+     * Returns an array of the Instrument Samples assigned to the Instrument.
+     *
+     * @return An array of Instrument Samples.
+     */
+    public InstrumentSampleData[] getInstrumentSamples()
+    {
+        HTTPInstrumentSampleData[] samples = m_sampleAry;
+        if ( samples == null )
+        {
+            synchronized ( m_samples )
+            {
+                m_sampleAry = new HTTPInstrumentSampleData[m_samples.size()];
+                m_samples.toArray( m_sampleAry );
+                samples = m_sampleAry;
+            }
+        }
+        return samples;
+    }
+    
+    /**
+     * Requests that a sample be created or that its lease be updated.
+     *
+     * @param description Description to assign to the new sample.
+     * @param interval Sample interval of the new sample.
+     * @param sampleCount Number of samples in the new sample.
+     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param sampleType The type of sample to be created.
+     */
+    public void createInstrumentSample( String description,
+                                        long interval,
+                                        int sampleCount,
+                                        long leaseTime,
+                                        int sampleType )
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        connection.getState( "create-sample.xml?name=" + urlEncode( getName() )
+            + "&description=" + urlEncode( description ) + "&interval=" + interval
+            + "&size=" + sampleCount + "&lease=" + leaseTime + "&type=" + sampleType );
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,325 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
+import org.apache.excalibur.instrument.client.InstrumentableData;
+import org.apache.excalibur.instrument.client.InstrumentManagerConnection;
+import org.apache.excalibur.instrument.client.InstrumentManagerData;
+
+/**
+ * A Connection to the remote InstrumentManager which connects using
+ *  the HTTP connector.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
+ * @since 4.1
+ */
+public class HTTPInstrumentManagerConnection
+    extends InstrumentManagerConnection
+{
+    private URL m_url;
+    
+    /** Flag which keeps track of whether or not the remote server was there
+    *   the last time we attempted to connect. */
+    private boolean m_connected;
+    
+    /** If we ever decide that we are not talking to an Instrument Manager then
+     *   disable the connection to avoid pounding the remote server with lots
+     *   of 404 requests. */
+    private boolean m_disabled;
+    
+    private HTTPInstrumentManagerData m_manager;
+    
+    private List m_leasedSamples = new ArrayList();
+    private HTTPInstrumentSampleData[] m_leasedSampleAry;
+
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentManagerConnection.
+     */
+    public HTTPInstrumentManagerConnection( URL url )
+    {
+        m_url = url;
+        m_connected = false;
+        
+        m_manager = new HTTPInstrumentManagerData( this );
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentManagerConnection Methods
+     *-------------------------------------------------------------*/
+    public void enableLogging( Logger logger )
+    {
+        super.enableLogging( logger );
+        m_manager.enableLogging( logger.getChildLogger( "manager" ) );
+    }
+    
+    /**
+     * Returns the key used to identify this object.
+     *
+     * @return The key used to identify this object.
+     */
+    public Object getKey()
+    {
+        return m_url;
+    }
+    
+    /**
+     * Returns true if connected.
+     *
+     * @return True if connected.
+     */
+    public boolean isConnected()
+    {
+        return m_connected;
+    }
+    
+    /**
+     * Returns the Instrument Manager.
+     *
+     * @return The Instrument Manager.
+     */
+    public InstrumentManagerData getInstrumentManager()
+    {
+        return m_manager;
+    }
+    
+    /**
+     * Returns the title to display in the tab for the connection.
+     *
+     * @return The tab title.
+     */
+    public String getTabTitle()
+    {
+        if ( m_disabled )
+        {
+            return "[DISABLED] " + super.getTabTitle();
+        }
+        else
+        {
+            return super.getTabTitle();
+        }
+    }
+
+    /**
+     * Invokes GC on the JVM running the InstrumentManager.
+     */
+    protected void invokeGC()
+    {
+        getState( "gc.xml" );
+    }
+
+    /**
+     * Saves the current state into a Configuration.
+     *
+     * @return The state as a Configuration.
+     */
+    public Configuration saveState()
+    {
+        synchronized( this )
+        {
+            DefaultConfiguration state = (DefaultConfiguration)super.saveState();
+            
+            state.setAttribute( "url", m_url.toExternalForm() );
+            
+            return state;
+        }
+    }
+
+    /**
+     * Loads the state from a Configuration object.
+     *
+     * @param state Configuration object to load state from.
+     *
+     * @throws ConfigurationException If there were any problems loading the
+     *                                state.
+     */
+    public void loadState( Configuration state )
+        throws ConfigurationException
+    {
+        synchronized( this )
+        {
+            super.loadState( state );
+            
+            // URL will have already been set.
+        }
+    }
+    
+    /**
+     * Gets a thread-safe snapshot of the leased sample list.
+     *
+     * @return A thread-safe snapshot of the leased sample list.
+     */
+    /*
+    public InstrumentSampleData[] getLeasedSamples()
+    {
+        InstrumentSampleData[] samples = m_leasedSampleAry;
+        if ( samples == null )
+        {
+            synchronized ( m_leasedSamples )
+            {
+                m_leasedSampleAry = new InstrumentSampleData[m_leasedSamples.size()];
+                m_leasedSamples.toArray( m_leasedSampleAry );
+                samples = m_leasedSampleAry;
+            }
+        }
+        return samples;
+    }
+    */
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the URL of the remote InstrumentManager.
+     *
+     * @return The URL of the remote InstrumentManager.
+     */
+    URL getURL()
+    {
+        return m_url;
+    }
+    
+    /**
+     * Requests the current state of the object at the specified path.
+     *  If the request fails for any reason, including not being valid
+     *  content then the method will return null.
+     *
+     * @param path The path of the object whose state is requested.
+     *
+     * @return The state as a Configuration object, or null if it failed.
+     */
+    Configuration getState( String path )
+    {
+        if ( m_disabled )
+        {
+            return null;
+        }
+        
+        URL url;
+        try
+        {
+            url = new URL( m_url, path );
+        }
+        catch ( MalformedURLException e )
+        {
+            getLogger().debug( "Request failed.", e );
+            return null;
+        }
+        
+        try
+        {
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+            
+            m_connected = true;
+            
+            if ( conn.getResponseCode() == conn.HTTP_OK )
+            {
+                InputStream is = conn.getInputStream();
+                try
+                {
+                    DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+                    try
+                    {
+                        return builder.build( is );
+                    }
+                    catch ( ConfigurationException e )
+                    {
+                        getLogger().warn( "Invalid XML reveived from the server.", e );
+                        return null;
+                    }
+                    catch ( org.xml.sax.SAXException e )
+                    {
+                        getLogger().warn( "Invalid XML reveived from the server.", e );
+                        return null;
+                    }
+                }
+                finally
+                {
+                    is.close();
+                }
+            }
+            else
+            {
+                if ( ( conn.getResponseCode() == 404 )
+                    && path.startsWith( "instrument-manager.xml" ) )
+                {
+                    getLogger().warn( "Requested " + url + " resulted in error code 404.  "
+                        + "Most likely not an Instrument Manager, disabling future requests." );
+                    m_disabled = true;
+                }
+                else
+                {
+                    getLogger().debug( "Response: " + conn.getResponseCode() + " : "
+                        + conn.getResponseMessage() );
+                }
+                return null;
+            }
+        }
+        catch ( IOException e )
+        {
+            String msg = e.getMessage();
+            if ( msg == null )
+            {
+                msg = e.toString();
+            }
+            
+            if ( msg.indexOf( "Connect" ) >= 0 )
+            {
+                // Hide the stack trace as the server is simply down.
+                getLogger().debug( "Request failed.  URL: " + url + "  Error: " + msg );
+            }
+            else
+            {
+                getLogger().debug( "Request failed.  URL: " + url + "  Error: ", e );
+            }
+            
+            m_connected = false;
+            return null;
+        }
+    }
+    
+    /*
+    private void updateLeasedSamples()
+    {
+        InstrumentSampleData[] samples = getLeasedSamples();
+        for ( int i = 0; i < samples.length; i++ )
+        {
+            InstrumentSampleData sample = samples[i];
+            sample.updateLease();
+        }
+    }
+    */
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,240 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.excalibur.instrument.client.InstrumentableData;
+import org.apache.excalibur.instrument.client.InstrumentManagerData;
+
+class HTTPInstrumentManagerData
+    extends AbstractHTTPData
+    implements InstrumentManagerData
+{
+    /* Name of the remote object. */
+    private String m_name;
+    
+    private List m_instrumentables = new ArrayList();
+    private HTTPInstrumentableData[] m_instrumentableAry;
+    private Map m_instrumentableMap = new HashMap();
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentManagerData.
+     */
+    HTTPInstrumentManagerData( HTTPInstrumentManagerConnection connection )
+    {
+        super( connection, connection.getURL().toExternalForm() );
+        
+        m_name = connection.getURL().toExternalForm();
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     * @param recurse True if state should be ignored and we should drill down
+     *                using data in this configuration.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration, boolean recurse )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        m_name = configuration.getAttribute( "name" );
+        
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug(
+                "Updated InstrumentManager '" + getName() + "' to version " + getStateVersion() );
+        }
+        
+        Configuration[] instrumentableConfs = configuration.getChildren( "instrumentable" );
+        for ( int i = 0; i < instrumentableConfs.length; i++ )
+        {
+            Configuration iaConf = instrumentableConfs[i];
+            String iaName = iaConf.getAttribute( "name" );
+            int iaStateVersion = iaConf.getAttributeAsInteger( "state-version" );
+            
+            HTTPInstrumentableData iaData;
+            synchronized ( m_instrumentables )
+            {
+                iaData = (HTTPInstrumentableData)m_instrumentableMap.get( iaName );
+                if ( iaData == null )
+                {
+                    // It is new.
+                    iaData = new HTTPInstrumentableData( this, iaName );
+                    iaData.enableLogging( getLogger().getChildLogger( iaName ) );
+                    m_instrumentables.add( iaData );
+                    m_instrumentableAry = null;
+                    m_instrumentableMap.put( iaName, iaData );
+                }
+            }
+            
+            if ( recurse )
+            {
+                iaData.update( iaConf, recurse );
+            }
+            else
+            {
+                if ( iaStateVersion != iaData.getStateVersion() )
+                {
+                    // Needs to be updated.
+                    iaData.update();
+                }
+            }
+        }
+    }
+    
+    /**
+     * Causes the InstrumentManagerData to update itself with the latest data
+     *  from the server.
+     *
+     * @return true if successful.
+     */
+    public boolean update()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration = connection.getState( "instrument-manager.xml?packed=true" );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration, false );
+                
+                //updateLeasedSamples();
+                
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        return false;
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentManagerData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the name.
+     *
+     * @return The name.
+     */
+    public String getName()
+    {
+        return m_name;
+    }
+    
+    /**
+     * Gets a thread-safe snapshot of the instrumentable list.
+     *
+     * @return A thread-safe snapshot of the instrumentable list.
+     */
+    public InstrumentableData[] getInstrumentables()
+    {
+        HTTPInstrumentableData[] instrumentables = m_instrumentableAry;
+        if ( instrumentables == null )
+        {
+            synchronized ( m_instrumentables )
+            {
+                m_instrumentableAry = new HTTPInstrumentableData[m_instrumentables.size()];
+                m_instrumentables.toArray( m_instrumentableAry );
+                instrumentables = m_instrumentableAry;
+            }
+        }
+        return instrumentables;
+    }
+    
+    /**
+     * Causes the the entire instrument tree to be updated in one call.  Very fast
+     *  when it is known that all or most data has changed.
+     *
+     * @return true if successful.
+     */
+    public boolean updateAll()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration =
+            connection.getState( "instrument-manager.xml?packed=true&recurse=true" );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration, true );
+                
+                //updateLeasedSamples();
+                
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Requests that a sample be created or that its lease be updated.
+     *
+     * @param instrumentName The full name of the instrument whose sample is
+     *                       to be created or updated.
+     * @param description Description to assign to the new sample.
+     * @param interval Sample interval of the new sample.
+     * @param sampleCount Number of samples in the new sample.
+     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param sampleType The type of sample to be created.
+     */
+    public void createInstrumentSample( String instrumentName,
+                                        String description,
+                                        long interval,
+                                        int sampleCount,
+                                        long leaseTime,
+                                        int sampleType )
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        connection.getState( "create-sample.xml?name=" + urlEncode( instrumentName )
+            + "&description=" + urlEncode( description ) + "&interval=" + interval
+            + "&size=" + sampleCount + "&lease=" + leaseTime + "&type=" + sampleType );
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,130 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import org.apache.excalibur.instrument.client.InstrumentSampleData;
+import org.apache.excalibur.instrument.client.InstrumentSampleSnapshotData;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+class HTTPInstrumentSampleData
+    extends AbstractHTTPInstrumentSampleElementData
+    implements InstrumentSampleData
+{
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentSampleData.
+     */
+    HTTPInstrumentSampleData( HTTPInstrumentData parent,
+                              String name )
+    {
+        super( (HTTPInstrumentManagerConnection)parent.getConnection(), parent, name );
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug(
+                "Updated Instrument Sample '" + getName() + "' to version " + getStateVersion() );
+        }
+    }
+    
+    /**
+     * Causes the InstrumentSampleData to update itself with the latest data
+     *  from the server.
+     *
+     * @return true if successful.
+     */
+    public boolean update()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration = connection.getState(
+            "sample.xml?packed=true&name=" + urlEncode( getName() ) );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration );
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        
+        return false;
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentSampleData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Requests that the sample's lease be updated.
+     */
+    public void updateLease()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        connection.getState( "sample-lease.xml?name=" + urlEncode( getName() ) );
+    }
+    
+    /**
+     * Returns a snapshot of the data in the sample.
+     *
+     * @return A snapshot of the sample.
+     */
+    public InstrumentSampleSnapshotData getSnapshot()
+    {
+        HTTPInstrumentSampleSnapshotData snapshot =
+            new HTTPInstrumentSampleSnapshotData( this, getName() );
+        snapshot.enableLogging( getLogger() );
+        if ( snapshot.update() )
+        {
+            return snapshot;
+        }
+        else
+        {
+            return null;
+        }
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,137 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.util.StringTokenizer;
+
+import org.apache.excalibur.instrument.client.InstrumentSampleSnapshotData;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+class HTTPInstrumentSampleSnapshotData
+    extends AbstractHTTPInstrumentSampleElementData
+    implements InstrumentSampleSnapshotData
+{
+    /** Array of values which make up the sample. */
+    private int[] m_samples;
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentSampleSnapshotData.
+     */
+    HTTPInstrumentSampleSnapshotData( HTTPInstrumentSampleData parent,
+                                      String name )
+    {
+        super( (HTTPInstrumentManagerConnection)parent.getConnection(), parent, name );
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug( "Updated Instrument Sample snapshot '" + getName() + "' "
+                + "to version " + getStateVersion() );
+        }
+        
+        m_samples = new int[getSize()];
+        
+        String rawSamples = configuration.getChild( "values" ).getValue( "" );
+        StringTokenizer st = new StringTokenizer( rawSamples, ", " );
+        
+        // The token count should always match the size.  But mne careful just in
+        //  case as the server may not be the same version.
+        int i = 0;
+        while ( st.hasMoreTokens() && ( i < m_samples.length ) )
+        {
+            int value;
+            try
+            {
+                value = Integer.parseInt( st.nextToken() );
+            }
+            catch ( NumberFormatException e )
+            {
+                value = 0;
+            }
+            m_samples[i] = value;
+            i++;
+        }
+    }
+    
+    /**
+     * Causes the InstrumentSampleSnapshotData to update itself with the latest
+     *  data from the server.
+     *
+     * @return true if successful.
+     */
+    public boolean update()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration = connection.getState(
+            "snapshot.xml?packed=true&name=" + urlEncode( getName() ) + "&compact=true" );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration );
+                
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        
+        return false;
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentSampleSnapshotData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns an array of the individual values which make up the sample.
+     *
+     * @return An array of sample values.
+     */
+    public int[] getSamples()
+    {
+        return m_samples;
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

Added: excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentableData.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/containerkit/instrument-client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentableData.java	Tue Jul 27 10:37:36 2004
@@ -0,0 +1,243 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.excalibur.instrument.client.http;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.excalibur.instrument.client.InstrumentableData;
+import org.apache.excalibur.instrument.client.InstrumentData;
+
+class HTTPInstrumentableData
+    extends AbstractHTTPElementData
+    implements InstrumentableData
+{
+    /* The registered flag of the remote object. */
+    private boolean m_registered;
+    
+    private List m_instrumentables = new ArrayList();
+    private HTTPInstrumentableData[] m_instrumentableAry;
+    private Map m_instrumentableMap = new HashMap();
+    
+    private List m_instruments = new ArrayList();
+    private HTTPInstrumentData[] m_instrumentAry;
+    private Map m_instrumentMap = new HashMap();
+    
+    /*---------------------------------------------------------------
+     * Constructors
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new HTTPInstrumentableData.
+     */
+    HTTPInstrumentableData( AbstractHTTPData parent,
+                            String name )
+    {
+        super( (HTTPInstrumentManagerConnection)parent.getConnection(), parent, name );
+        
+        m_registered = false;
+    }
+    
+    /*---------------------------------------------------------------
+     * AbstractHTTPElementData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Update the contents of the object using values from the Configuration object.
+     *
+     * @param configuration Configuration object to load from.
+     * @param recurse True if state should be ignored and we should drill down
+     *                using data in this configuration.
+     *
+     * @throws ConfigurationException If there are any problems.
+     */
+    protected void update( Configuration configuration, boolean recurse )
+        throws ConfigurationException
+    {
+        super.update( configuration );
+        
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug(
+                "Updated Instrumentable '" + getName() + "' to version " + getStateVersion() );
+        }
+        
+        m_registered = configuration.getAttributeAsBoolean( "registered" );
+        
+        Configuration[] instrumentableConfs = configuration.getChildren( "instrumentable" );
+        for ( int i = 0; i < instrumentableConfs.length; i++ )
+        {
+            Configuration iaConf = instrumentableConfs[i];
+            String iaName = iaConf.getAttribute( "name" );
+            int iaStateVersion = iaConf.getAttributeAsInteger( "state-version" );
+            
+            HTTPInstrumentableData iaData;
+            synchronized( m_instrumentables )
+            {
+                iaData = (HTTPInstrumentableData)m_instrumentableMap.get( iaName );
+                if ( iaData == null )
+                {
+                    // It is new.
+                    iaData = new HTTPInstrumentableData( this, iaName );
+                    iaData.enableLogging( getLogger().getChildLogger( iaName ) );
+                    m_instrumentables.add( iaData );
+                    m_instrumentableAry = null;
+                    m_instrumentableMap.put( iaName, iaData );
+                }
+            }
+            
+            if ( recurse )
+            {
+                iaData.update( iaConf, recurse );
+            }
+            else
+            {
+                if ( iaStateVersion != iaData.getStateVersion() )
+                {
+                    // Needs to be updated.
+                    iaData.update();
+                }
+            }
+        }
+        
+        Configuration[] instrumentConfs = configuration.getChildren( "instrument" );
+        for ( int i = 0; i < instrumentConfs.length; i++ )
+        {
+            Configuration iConf = instrumentConfs[i];
+            String iName = iConf.getAttribute( "name" );
+            int iStateVersion = iConf.getAttributeAsInteger( "state-version" );
+            
+            HTTPInstrumentData iData;
+            synchronized( m_instruments )
+            {
+                iData = (HTTPInstrumentData)m_instrumentMap.get( iName );
+                if ( iData == null )
+                {
+                    // It is new.
+                    iData = new HTTPInstrumentData( this, iName );
+                    iData.enableLogging( getLogger().getChildLogger( iName ) );
+                    m_instruments.add( iData );
+                    m_instrumentAry = null;
+                    m_instrumentMap.put( iName, iData );
+                }
+            }
+            
+            if ( recurse )
+            {
+                iData.update( iConf, recurse );
+            }
+            else
+            {
+                if ( iStateVersion != iData.getStateVersion() )
+                {
+                    // Needs to be updated.
+                    iData.update();
+                }
+            }
+        }
+    }
+    
+    /**
+     * Causes the InstrumentableData to update itself with the latest data from
+     *  the server.
+     *
+     * @return true if successful.
+     */
+    public boolean update()
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        Configuration configuration = connection.getState(
+            "instrumentable.xml?packed=true&name=" + urlEncode( getName() ) );
+        if ( configuration != null )
+        {
+            try
+            {
+                update( configuration, false );
+                return true;
+            }
+            catch ( ConfigurationException e )
+            {
+                getLogger().debug( "Unable to update.", e );
+            }
+        }
+        
+        return false;
+    }
+    
+    /*---------------------------------------------------------------
+     * InstrumentableData Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Returns the registered flag of the remote object.
+     *
+     * @return The registered flag of the remote object.
+     */
+    public boolean isRegistered()
+    {
+        return m_registered;
+    }
+    
+    /**
+     * Gets a thread-safe snapshot of the child instrumentable list.
+     *
+     * @return A thread-safe snapshot of the child instrumentable list.
+     */
+    public InstrumentableData[] getInstrumentables()
+    {
+        HTTPInstrumentableData[] instrumentables = m_instrumentableAry;
+        if ( instrumentables == null )
+        {
+            synchronized ( m_instrumentables )
+            {
+                m_instrumentableAry = new HTTPInstrumentableData[m_instrumentables.size()];
+                m_instrumentables.toArray( m_instrumentableAry );
+                instrumentables = m_instrumentableAry;
+            }
+        }
+        return instrumentables;
+    }
+    
+    /**
+     * Gets a thread-safe snapshot of the instrument list.
+     *
+     * @return A thread-safe snapshot of the instrument list.
+     */
+    public InstrumentData[] getInstruments()
+    {
+        HTTPInstrumentData[] instruments = m_instrumentAry;
+        if ( instruments == null )
+        {
+            synchronized ( m_instruments )
+            {
+                m_instrumentAry = new HTTPInstrumentData[m_instruments.size()];
+                m_instruments.toArray( m_instrumentAry );
+                instruments = m_instrumentAry;
+            }
+        }
+        return instruments;
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+}
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: scm-unsubscribe@excalibur.apache.org
For additional commands, e-mail: scm-help@excalibur.apache.org