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 2005/09/08 05:26:39 UTC

svn commit: r279496 - /excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/

Author: leif
Date: Wed Sep  7 20:26:34 2005
New Revision: 279496

URL: http://svn.apache.org/viewcvs?rev=279496&view=rev
Log:
Rework the way states are loaded and saved so it is now possible to define sample name translations so that sample state files can be easily preserved even if the name of the instrument is changed.
The state files are also much simpler and smaller now.  They no longer contain data which does not contain any state information, or surpurfluous information about the location of samples in the instrument tree.   Old sample state files can still be read without any problems.

Modified:
    excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/AbstractInstrumentSample.java
    excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/DefaultInstrumentManagerImpl.java
    excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentProxy.java
    excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentSample.java
    excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentableProxy.java

Modified: excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/AbstractInstrumentSample.java
URL: http://svn.apache.org/viewcvs/excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/AbstractInstrumentSample.java?rev=279496&r1=279495&r2=279496&view=diff
==============================================================================
--- excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/AbstractInstrumentSample.java (original)
+++ excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/AbstractInstrumentSample.java Wed Sep  7 20:26:34 2005
@@ -534,6 +534,7 @@
      * @return True if state information exists which should be written to
      *         a state file.
      */
+    /*
     public boolean hasState()
     {
         // If this sample is not configured and its lease time is 0, then it
@@ -545,6 +546,7 @@
         
         return true;
     }
+    */
     
     /**
      * Writes the current state to a PrintWriter as XML.
@@ -566,59 +568,69 @@
 
         synchronized( this )
         {
+            
             // Always update the sample so its state will be correct when saved.
             long now = System.currentTimeMillis();
             update = update( now, false );
             value = getValueInner();
             time = m_time;
             
-            // Open the node.
-            out.print( "<sample name=\"" );
-            out.print( XMLUtil.getXMLSafeString( m_name ) );
-            out.print( "\" type=\"" );
-            out.print( InstrumentSampleUtils.getInstrumentSampleTypeName( getType() ) );
-            out.print( "\" interval=\"" );
-            out.print( m_interval );
-            out.print( "\" size=\"" );
-            out.print( m_size );
-            out.print( "\" time=\"" );
-            out.print( m_time );
-            out.print( "\"" );
-            if( getLeaseExpirationTime() > 0 )
-            {
-                out.print( " lease-expiration=\"" );
-                out.print( getLeaseExpirationTime() );
-                out.print( "\"" );
-                
-                // If the sample is permanent then its description will be set in the configuration
-                //  file and does not need to be saved here as well.
-                out.print( " description=\"" );
-                out.print( XMLUtil.getXMLSafeString( m_description ) );
-                out.print( "\"" );
-            }
-
-            // Let subclasses add additional attributes.
-            writeStateAttributes( out );
-            
             String history = getHistoryList();
             
-            if ( history == null )
+            if( ( getLeaseExpirationTime() == 0 ) && ( history == null ) )
             {
-                // No history.  Childless node.
-                out.println( "/>" );
+                // This is a permanent sample with no data points,  there is no point therefor
+                //  in writing it to the state file.
+                // Do nothing.  We may have updated though so handle that below.
             }
             else
             {
-                // Have history.
-                out.println( ">" );
-                
-                // Save the history samples so that the newest is first.
-                out.print( "<history>" );
-                out.print( history );
-                out.println( "</history>" );
+                // Open the node.
+                out.print( "<sample name=\"" );
+                out.print( XMLUtil.getXMLSafeString( m_name ) );
+                out.print( "\" type=\"" );
+                out.print( InstrumentSampleUtils.getInstrumentSampleTypeName( getType() ) );
+                out.print( "\" interval=\"" );
+                out.print( m_interval );
+                out.print( "\" size=\"" );
+                out.print( m_size );
+                out.print( "\" time=\"" );
+                out.print( m_time );
+                out.print( "\"" );
+                if( getLeaseExpirationTime() != 0 )
+                {
+                    out.print( " lease-expiration=\"" );
+                    out.print( getLeaseExpirationTime() );
+                    out.print( "\"" );
+                    
+                    // If the sample is permanent then its description will be set in the configuration
+                    //  file and does not need to be saved here as well.
+                    out.print( " description=\"" );
+                    out.print( XMLUtil.getXMLSafeString( m_description ) );
+                    out.print( "\"" );
+                }
+    
+                // Let subclasses add additional attributes.
+                writeStateAttributes( out );
                 
-                // Close the node.
-                out.println( "</sample>" );
+                if ( history == null )
+                {
+                    // No history.  Childless node.
+                    out.println( "/>" );
+                }
+                else
+                {
+                    // Have history.
+                    out.println( ">" );
+                    
+                    // Save the history samples so that the newest is first.
+                    out.print( "<history>" );
+                    out.print( history );
+                    out.println( "</history>" );
+                    
+                    // Close the node.
+                    out.println( "</sample>" );
+                }
             }
         }
 

Modified: excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/DefaultInstrumentManagerImpl.java
URL: http://svn.apache.org/viewcvs/excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/DefaultInstrumentManagerImpl.java?rev=279496&r1=279495&r2=279496&view=diff
==============================================================================
--- excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/DefaultInstrumentManagerImpl.java (original)
+++ excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/DefaultInstrumentManagerImpl.java Wed Sep  7 20:26:34 2005
@@ -30,6 +30,8 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.avalon.framework.activity.Disposable;
 import org.apache.avalon.framework.activity.Initializable;
@@ -88,7 +90,7 @@
     private long m_maxLeasedSampleLease;
     
     /** List of configured connectors. */
-    private ArrayList m_connectors = new ArrayList();
+    private List m_connectors = new ArrayList();
 
     /** State file. */
     private File m_stateFile;
@@ -103,7 +105,7 @@
     private Object m_semaphore = new Object();
 
     /** HashMap of all of the registered InstrumentableProxies by their keys. */
-    private HashMap m_instrumentableProxies = new HashMap();
+    private Map m_instrumentableProxies = new HashMap();
 
     /** Optimized array of the InstrumentableProxies. */
     private InstrumentableProxy[] m_instrumentableProxyArray;
@@ -112,11 +114,20 @@
     private InstrumentableDescriptor[] m_instrumentableDescriptorArray;
 
     /** List of leased InstrumentSamples. */
-    private ArrayList m_leasedInstrumentSamples = new ArrayList();
+    private List m_leasedInstrumentSamples = new ArrayList();
     
     /** Optimized array of the leased InstrumentSamples. */
     private InstrumentSample[] m_leasedInstrumentSampleArray;
     
+    /** Logger dedicated to logging translations. */
+    private Logger m_translationLogger;
+    
+    /** Map of all registered translations. */
+    private Map m_nameTranslations = new HashMap();
+    
+    /** Optimized array of the registered translations. */
+    private String[][] m_nameTranslationArray;
+    
     /**
      * Thread used to keep the instruments published by the InstrumentManager
      *  up to date.
@@ -226,6 +237,8 @@
     public void configure( Configuration configuration )
         throws ConfigurationException
     {
+        m_translationLogger = getLogger().getChildLogger( "translation" );
+        
         // Register the InstrumentManager as an Instrumentable.  This must be done before
         //  the configuration and state file is loaded or our own instruments will not yet
         //  have proxies.
@@ -254,6 +267,24 @@
             m_maxLeasedSampleLease = 1000L *
                 configuration.getChild( "max-leased-sample-lease" ).getValueAsInteger( 86400 );
             
+            // Configure any translations
+            Configuration translationsConf = configuration.getChild( "translations" );
+            Configuration[] translationConfs = translationsConf.getChildren( "translation" );
+            for( int i = 0; i < translationConfs.length; i++ )
+            {
+                Configuration translationConf = translationConfs[i];
+                String source = translationConf.getAttribute( "source" );
+                String target = translationConf.getAttribute( "target" );
+                try
+                {
+                    registerNameTranslationInner( source, target );
+                }
+                catch ( IllegalArgumentException e )
+                {
+                    throw new ConfigurationException( e.getMessage(), translationConf );
+                }
+            }
+            
             // Configure the instrumentables.
             Configuration instrumentablesConf = configuration.getChild( "instrumentables" );
             Configuration[] instrumentableConfs =
@@ -544,6 +575,36 @@
     }
     
     /**
+     * Registers a name translation that will be applied to all named based
+     *  lookups of instrumentables, instruments, and samples.   The more
+     *  translations that are registered, the greater the impact on name
+     *  based lookups will be.
+     * <p>
+     * General operation of the instrument manager will not be affected as
+     *  collection on sample data is always done using direct object
+     *  references.
+     * <p>
+     * Translations can be registered for exact name matches, or for
+     *  the bases of names.  Any translation which ends in a '.' will
+     *  imply a translation to any name beginning with that name base.
+     *  If the source ends with a '.' then the target must as well.
+     * 
+     * @param source The source name or name base of the translation.
+     * @param target The target name or name base of the translation.
+     *
+     * @throws IllegalArgumentException If the one but not both of the source
+     *                                  and target parameters end in '.'.
+     */
+    public void registerNameTranslation( String source, String target )
+        throws IllegalArgumentException
+    {
+        synchronized( m_semaphore )
+        {
+            registerNameTranslationInner( source, target );
+        }
+    }
+    
+    /**
      * Returns a InstrumentableDescriptor based on its name or the name of any
      *  of its children.
      *
@@ -940,32 +1001,100 @@
     public void loadStateFromConfiguration( Configuration state )
         throws ConfigurationException
     {
+        // When loading state, the only thing that we are really interrested in are the samples.
+        //  Don't bother looking anything up until one is found.  Doing it this way is also
+        //  critical to make name translations work correctly.
+        
+        // Drill down into Instrumentables and Instruments by recursing into this method.
+        //  This is not used by state files saved with version 2.2 or newer, but older
+        //  versions of the instrument manager saved their states in a tree structure.
         Configuration[] instrumentableConfs = state.getChildren( "instrumentable" );
         for( int i = 0; i < instrumentableConfs.length; i++ )
         {
-            Configuration instrumentableConf = instrumentableConfs[ i ];
-            String instrumentableName = instrumentableConf.getAttribute( "name" );
-            InstrumentableProxy instrumentableProxy = getInstrumentableProxy( instrumentableName );
-            if( instrumentableProxy == null )
-            {
-                // The Instrumentable was in the state file, but has not yet
-                //  been registered.  It is possible that it will be registered
-                //  at a later time.  For now it needs to be created.
-                instrumentableProxy = new InstrumentableProxy(
-                    this, null, instrumentableName, instrumentableName );
-                instrumentableProxy.enableLogging( getLogger() );
-                incrementInstrumentableCount();
-                m_instrumentableProxies.put( instrumentableName, instrumentableProxy );
-
-                // Clear the optimized arrays
-                m_instrumentableProxyArray = null;
-                m_instrumentableDescriptorArray = null;
-            }
+            loadStateFromConfiguration( instrumentableConfs[i] );
+        }
+        Configuration[] instrumentConfs = state.getChildren( "instrument" );
+        for( int i = 0; i < instrumentConfs.length; i++ )
+        {
+            loadStateFromConfiguration( instrumentConfs[i] );
+        }
+        
+        // Look for any samples.
+        Configuration[] sampleConfs = state.getChildren( "sample" );
+        for( int i = 0; i < sampleConfs.length; i++ )
+        {
+            Configuration sampleConf = sampleConfs[i];
+            
+            // Obtain and translate the sample name.
+            String sampleName = getTranslatedName( sampleConf.getAttribute( "name" ) );
             
-            instrumentableProxy.loadState( instrumentableConf );
+            // Before we do anything, decide how we want to handle the sample.
+            long now = System.currentTimeMillis();
+            long leaseExpirationTime = state.getAttributeAsLong( "lease-expiration", 0 );
+            if ( leaseExpirationTime == 0 )
+            {
+                // This is the saved state of a permanent sample.  We only want to load it
+                //  if the instrument and sample exists.  If it does not exist then it means
+                //  that the user changed the configuration so the sample is no longer
+                //  permanent.
+                
+                // Look for the existing instrument proxy.
+                InstrumentProxy instrumentProxy = getInstrumentProxyForSample( sampleName, false );
+                if ( instrumentProxy == null )
+                {
+                    // The instrument did not exist, so we want to skip this state.
+                    getLogger().info(
+                        "Skipping old permantent sample from state due to missing instrument: "
+                        + sampleName );
+                }
+                else
+                {
+                    // The instrument exists, but the sample may not.  That is decided within
+                    //  the instrument.
+                    InstrumentSample sample = instrumentProxy.loadSampleState( sampleConf );
+                    if ( sample == null )
+                    {
+                        getLogger().info(
+                            "Skipping old permantent sample from state: " + sampleName );
+                    }
+                    else
+                    {
+                        if ( getLogger().isDebugEnabled() )
+                        {
+                            getLogger().debug( "Load permanent sample state: " + sampleName );
+                        }
+                    }
+                }
+            }
+            else if ( leaseExpirationTime > now )
+            {
+                // This is a leased sample that has not yet expired.  Even if the sample
+                //  or even its instrument does not yet exist, we want to go ahead and
+                //  create it.  It is possible for instruments and samples to be created
+                //  a while after the application has been started.
+                
+                // Get the instrument.  Will never return null.
+                InstrumentProxy instrumentProxy = getInstrumentProxyForSample( sampleName, true );
+                
+                // Load the sample state.
+                instrumentProxy.loadSampleState( sampleConf );
+                
+                if ( getLogger().isDebugEnabled() )
+                {
+                    getLogger().debug( "Load leased sample state : " + sampleName );
+                }
+            }
+            else
+            {
+                // This sample has expired since the state was saved.  Do nothing.
+                if ( getLogger().isDebugEnabled() )
+                {
+                    getLogger().debug( "Skip expired sample state: " + sampleName );
+                }
+            }
         }
         
-        stateChanged();
+        // If anything was actually loaded then stateChanged() will be called from the samples.
     }
 
     /**
@@ -1104,11 +1233,7 @@
         
         for( int i = 0; i < instrumentableProxies.length; i++ )
         {
-            InstrumentableProxy instrumentable = instrumentableProxies[i];
-            if ( instrumentable.hasState() )
-            {
-                instrumentable.writeState( out );
-            }
+            instrumentableProxies[i].writeState( out );
         }
     
         // Close off the main node.
@@ -1273,7 +1398,203 @@
         m_stateSavesInstrument.increment();
         m_stateSaveTimeInstrument.setValue( (int)( System.currentTimeMillis() - now ) );
     }
-
+    
+    /**
+     * Updates the cached array of registered name translations taking
+     *  synchronization into account.
+     *
+     * @return An array of the String[2]s representing the registered name
+     *         translations.
+     */
+    private String[][] updateNameTranslationArray()
+    {
+        synchronized( m_semaphore )
+        {
+            String[][] nameTranslations = new String[m_nameTranslations.size()][2];
+            int i = 0;
+            for ( Iterator iter = m_nameTranslations.entrySet().iterator(); iter.hasNext(); i++ )
+            {
+                Map.Entry entry = (Map.Entry)iter.next();
+                nameTranslations[i][0] = (String)entry.getKey();
+                nameTranslations[i][1] = (String)entry.getValue();
+            }
+            
+            // Once we are done modifying this array, set it to the variable accessable outside
+            //  of synchronization.
+            m_nameTranslationArray = nameTranslations;
+            
+            return nameTranslations;
+        }
+    }
+    
+    /**
+     * Translates a item name depending on a set of configured translations.
+     *  If the name does not exist as a translation then the requested name will
+     *  be returned unmodified.
+     *
+     * @param name Requested name.
+     *
+     * @return target name.
+     */
+    String getTranslatedName( String name )
+    {
+        String[][] nameTranslations = m_nameTranslationArray;
+        if( nameTranslations == null )
+        {
+            nameTranslations = updateNameTranslationArray();
+        }
+        
+        for ( int i = 0; i < nameTranslations.length; i++ )
+        {
+            String[] nameTranslation = nameTranslations[i];
+            
+            if ( name.startsWith( nameTranslation[0] ) )
+            {
+                // Match
+                if ( name.equals( nameTranslation[0] ) )
+                {
+                    // Exact match
+                    String newName = nameTranslation[1];
+                    
+                    if ( m_translationLogger.isDebugEnabled() )
+                    {
+                        m_translationLogger.debug(
+                            "Translate \"" + name + "\" to \"" + newName + "\"" );
+                    }
+                    
+                    return newName;
+                }
+                else if ( nameTranslation[0].endsWith( "." ) )
+                {
+                    // Beginning match
+                    String newName =
+                        nameTranslation[1] + name.substring( nameTranslation[0].length() );
+                    
+                    if ( m_translationLogger.isDebugEnabled() )
+                    {
+                        m_translationLogger.debug(
+                            "Translate \"" + name + "\" to \"" + newName + "\"" );
+                    }
+                    
+                    return newName;
+                }
+                else
+                {
+                    // The name happened to match the beginning of this name, but it was not meant
+                    //  as a base translation.
+                }
+            }
+        }
+        
+        // No match.
+        return name;
+    }
+    
+    /**
+     */
+    private InstrumentableProxy getInstrumentableProxy( String instrumentableName, boolean create )
+    {
+        //getLogger().debug( "getInstrumentableProxy( " + instrumentableName + ", " + create + " )" );
+        // The instrumable name may begin with the name of a parent Instrumentable
+        int pos = instrumentableName.lastIndexOf( '.' );
+        if ( pos <= 0 )
+        {
+            // This is a root level instrumentable.  Look for it within the Instrument Manager.
+            InstrumentableProxy instrumentableProxy;
+            synchronized( m_semaphore )
+            {
+                instrumentableProxy =
+                    (InstrumentableProxy)m_instrumentableProxies.get( instrumentableName );
+                
+                if ( ( instrumentableProxy == null ) && create )
+                {
+                    //getLogger().debug( "     New Instrumentable" );
+                    // Not found, create it.
+                    instrumentableProxy = new InstrumentableProxy(
+                        this, null, instrumentableName, instrumentableName );
+                    instrumentableProxy.enableLogging( getLogger() );
+                    incrementInstrumentableCount();
+                    m_instrumentableProxies.put( instrumentableName, instrumentableProxy );
+    
+                    // Clear the optimized arrays
+                    m_instrumentableProxyArray = null;
+                    m_instrumentableDescriptorArray = null;
+                }
+            }
+            
+            //getLogger().debug( "  -> " + instrumentableProxy );
+            return instrumentableProxy;
+        }
+        else
+        {
+            String parentInstrumentableName = instrumentableName.substring( 0, pos );
+            
+            // See if the parent Instrumentable exists.
+            InstrumentableProxy parentInstrumentableProxy =
+                getInstrumentableProxy( parentInstrumentableName, create );
+            if ( parentInstrumentableProxy == null )
+            {
+                // Parent Instrumentable did not exist, so the Instrumentable did not exist.
+                //  Will not get here if create is true.
+                return null;
+            }
+            
+            // Locate the Instrumentable within the parent Instrumentable.
+            return parentInstrumentableProxy.getChildInstrumentableProxy(
+                instrumentableName, create );
+        }
+    }
+    
+    /**
+     * @throws IllegalArgumentException If the specified instrumentName is invalid.
+     */
+    private InstrumentProxy getInstrumentProxy( String instrumentName, boolean create )
+        throws IllegalArgumentException
+    {
+        //getLogger().debug( "getInstrumentProxy( " + instrumentName + ", " + create + " )" );
+        // The instrument name must always begin with the name of an Instrumentable
+        int pos = instrumentName.lastIndexOf( '.' );
+        if ( pos <= 0 )
+        {
+            throw new IllegalArgumentException(
+                "\"" + instrumentName + "\" is not a valid instrument name." );
+        }
+        String instrumentableName = instrumentName.substring( 0, pos );
+        
+        // See if the Instrumentable exists.
+        InstrumentableProxy instrumentableProxy =
+            getInstrumentableProxy( instrumentableName, create );
+        if ( instrumentableProxy == null )
+        {
+            // Instrumentable did not exist, so the instrument did not exist.  Will not get here
+            //  if create is true.
+            return null;
+        }
+        
+        // Locate the instrument within the Instrumentable.
+        return instrumentableProxy.getInstrumentProxy( instrumentName, create );
+    }
+    
+    /**
+     * @throws IllegalArgumentException If the specified sampleName is invalid.
+     */
+    private InstrumentProxy getInstrumentProxyForSample( String sampleName, boolean create )
+        throws IllegalArgumentException
+    {
+        //getLogger().debug( "getInstrumentProxyForSample( " + sampleName + ", " + create + " )" );
+        // The sample name must always begin with the name of an Instrument
+        int pos = sampleName.lastIndexOf( '.' );
+        if ( pos <= 0 )
+        {
+            throw new IllegalArgumentException(
+                "\"" + sampleName + "\" is not a valid instrument sample name." );
+        }
+        String instrumentName = sampleName.substring( 0, pos );
+        
+        // Lookup the Instrument.
+        return getInstrumentProxy( instrumentName, create );
+    }
+    
     /**
      * Returns a InstrumentableDescriptor based on its name or the name of any
      *  of its children.
@@ -1497,6 +1818,56 @@
 
             return m_instrumentableDescriptorArray;
         }
+    }
+    
+    /**
+     * Registers a name translation that will be applied to all named based
+     *  lookups of instrumentables, instruments, and samples.   The more
+     *  translations that are registered, the greater the impact on name
+     *  based lookups will be.
+     * <p>
+     * General operation of the instrument manager will not be affected as
+     *  collection on sample data is always done using direct object
+     *  references.
+     * <p>
+     * Translations can be registered for translations of sample names up to
+     *  and including the name of the instrument.  This means that all source
+     *  and target names must end in a '.'.
+     * <p>
+     * This method should only be called when m_semaphore is synchronized.
+     * 
+     * @param source The source name or name base of the translation.
+     * @param target The target name or name base of the translation.
+     *
+     * @throws IllegalArgumentException If either the source or target does
+     *                                  not end in a '.' or is invalid.
+     */
+    private void registerNameTranslationInner( String source, String target )
+        throws IllegalArgumentException
+    {
+        if ( !source.endsWith( "." ) )
+        {
+            throw new IllegalArgumentException( "The translation source must end with a '.'." );
+        }
+        if ( !target.endsWith( "." ) )
+        {
+            throw new IllegalArgumentException( "The translation target must end with a '.'." );
+        }
+        
+        // No component of the source or target name may be 0 length.
+        if ( source.startsWith( "." ) || ( source.indexOf( ".." ) >= 0 ) )
+        {
+            throw new IllegalArgumentException(
+                "The translation source is invalid: \"" + source + "\"." );
+        }
+        if ( target.startsWith( "." ) || ( target.indexOf( ".." ) >= 0 ) )
+        {
+            throw new IllegalArgumentException(
+                "The translation target is invalid: \"" + target + "\"." );
+        }
+        
+        m_nameTranslations.put( source, target );
+        m_nameTranslationArray = null;
     }
 
     /**

Modified: excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentProxy.java
URL: http://svn.apache.org/viewcvs/excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentProxy.java?rev=279496&r1=279495&r2=279496&view=diff
==============================================================================
--- excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentProxy.java (original)
+++ excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentProxy.java Wed Sep  7 20:26:34 2005
@@ -674,15 +674,15 @@
     /**
      * Returns a InstrumentSample based on its name.
      *
-     * @param InstrumentSampleName Name of the InstrumentSample being requested.
+     * @param instrumentSampleName Name of the InstrumentSample being requested.
      *
      * @return The requested InstrumentSample or null if does not exist.
      */
-    InstrumentSample getInstrumentSample( String InstrumentSampleName )
+    InstrumentSample getInstrumentSample( String instrumentSampleName )
     {
         synchronized(this)
         {
-            return (InstrumentSample)m_samples.get( InstrumentSampleName );
+            return (InstrumentSample)m_samples.get( instrumentSampleName );
         }
     }
     
@@ -729,9 +729,12 @@
                                              long sampleLease,
                                              int sampleType )
     {
-        getLogger().debug( "Create new sample for " + m_name + ": interval=" + sampleInterval +
-            ", size=" + sampleSize + ", lease=" + sampleLease + ", type=" +
-            InstrumentSampleUtils.getInstrumentSampleTypeName( sampleType ) );
+        if ( getLogger().isDebugEnabled() )
+        {
+            getLogger().debug( "Create new sample for " + m_name + ": interval=" + sampleInterval +
+                ", size=" + sampleSize + ", lease=" + sampleLease + ", type=" +
+                InstrumentSampleUtils.getInstrumentSampleTypeName( sampleType ) );
+        }
         
         DefaultInstrumentManagerImpl manager = m_instrumentableProxy.getInstrumentManager();
         
@@ -991,124 +994,96 @@
     }
     
     /**
-     * Used to test whether or not any state information exists prior to
-     *  writeState() being called.  This process is not synchronized so it
-     *  is possible that the return value will no longer be accurate when
-     *  writeState is actually called.  For the purpose of writing the
-     *  state however this is accurate enough.
-     *
-     * @return True if state information exists which should be written to
-     *         a state file.
-     */
-    boolean hasState()
-    {
-        // Check samples.
-        InstrumentSample[] samples = getInstrumentSamples();
-        for ( int i = 0; i < samples.length; i++ )
-        {
-            InstrumentSample sample = samples[i];
-            if ( sample.hasState() )
-            {
-                return true;
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
      * Writes the current state to a PrintWriter as XML.
      *
      * @param out The PrintWriter to which the state should be written.
      */
     void writeState( PrintWriter out )
     {
-        // Open the node.
-        out.print( "<instrument name=\"" );
-        out.print( XMLUtil.getXMLSafeString( m_name ) );
-        out.println( "\">" );
+        // Samples are the only things written to the state, so all we need to do is drill down
+        //  to them.
         
         // Write out the states of any samples.
         InstrumentSample[] samples = getInstrumentSamples();
         for ( int i = 0; i < samples.length; i++ )
         {
-            InstrumentSample sample = samples[i];
-            if ( sample.hasState() )
-            {
-                sample.writeState( out );
-            }
+            samples[i].writeState( out );
         }
-        
-        // Close the node.
-        out.println( "</instrument>" );
     }
     
     /**
-     * Loads the state into the Instrument.
+     * Loads the state of an Instrument Sample.  If the does not exist and the
+     *  sample is leased then it will be created.
      *
      * @param state Configuration object to load state from.
      *
+     * @return The sample into which the state was loaded.  If the sample
+     *         did not exist and was not created then null is returned.
+     *
      * @throws ConfigurationException If there were any problems loading the
      *                                state.
      */
-    void loadState( Configuration state ) throws ConfigurationException
+    InstrumentSample loadSampleState( Configuration state ) throws ConfigurationException
     {
+        //getLogger().debug( "instrument loadSampleState() " + m_name + " to " + this );
+        InstrumentSample sample;
         synchronized( this )
         {
-            Configuration[] instrumentSampleConfs = state.getChildren( "sample" );
-            for ( int i = 0; i < instrumentSampleConfs.length; i++ )
-            {
-                Configuration instrumentSampleConf = instrumentSampleConfs[i];
-                
-                int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType(
-                    instrumentSampleConf.getAttribute( "type" ) );
-                long sampleInterval = instrumentSampleConf.getAttributeAsLong( "interval" );
-                int sampleSize = instrumentSampleConf.getAttributeAsInteger( "size", 1 );
-                
-                // Build the sample name from its attributes.  This makes it
-                //  possible to avoid forcing the user to maintain a name as well.
-                String fullSampleName = InstrumentSampleUtils.generateFullInstrumentSampleName(
-                    m_name, sampleType, sampleInterval, sampleSize );
-                InstrumentSample sample = getInstrumentSample( fullSampleName );
-                if ( sample == null )
+            Configuration instrumentSampleConf = state;
+            
+            int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType(
+                instrumentSampleConf.getAttribute( "type" ) );
+            long sampleInterval = instrumentSampleConf.getAttributeAsLong( "interval" );
+            int sampleSize = instrumentSampleConf.getAttributeAsInteger( "size", 1 );
+            
+            // Build the sample name from its attributes.  This makes it
+            //  possible to avoid forcing the user to maintain a name as well.
+            String fullSampleName = InstrumentSampleUtils.generateFullInstrumentSampleName(
+                m_name, sampleType, sampleInterval, sampleSize );
+            sample = getInstrumentSample( fullSampleName );
+            if ( sample == null )
+            {
+                // Sample does not exist, see if it is a leased sample.
+                long leaseExpirationTime =
+                    instrumentSampleConf.getAttributeAsLong( "lease-expiration", 0 );
+                if ( leaseExpirationTime > 0 )
                 {
-                    // Sample does not exist, see if it is a leased sample.
-                    long leaseExpirationTime =
-                        instrumentSampleConf.getAttributeAsLong( "lease-expiration", 0 );
-                    if ( leaseExpirationTime > 0 )
-                    {
-                        
-                        String sampleName = InstrumentSampleUtils.generateInstrumentSampleName(
-                            sampleType, sampleInterval, sampleSize );
-                        String sampleDescription =
-                            instrumentSampleConf.getAttribute( "description", sampleName );
-                        
-                        // Create the sample with an expiration time of 1.  This will be expired
-                        //  but not permanent.  It will be set with the correct
-                        //  expiration time will be set when its state is loaded.
-                        AbstractInstrumentSample instrumentSample = 
-                            (AbstractInstrumentSample)InstrumentSampleFactory.getInstrumentSample(
-                            this, sampleType, fullSampleName, sampleInterval, sampleSize,
-                            sampleDescription, 1 );
-                        instrumentSample.enableLogging( getLogger() );
-                        instrumentSample.loadState( instrumentSampleConf );
-                        
-                        addInstrumentSample( instrumentSample );
-                    }
-                    else
-                    {
-                        getLogger().debug( "InstrumentSample entry ignored while loading state " +
-                            "because the sample does not exist: " + fullSampleName );
-                    }
+                    
+                    String sampleName = InstrumentSampleUtils.generateInstrumentSampleName(
+                        sampleType, sampleInterval, sampleSize );
+                    String sampleDescription =
+                        instrumentSampleConf.getAttribute( "description", sampleName );
+                    
+                    // Create the sample with an expiration time of 1.  This will be expired
+                    //  but not permanent.  It will be set with the correct
+                    //  expiration time will be set when its state is loaded.
+                    AbstractInstrumentSample instrumentSample = 
+                        (AbstractInstrumentSample)InstrumentSampleFactory.getInstrumentSample(
+                        this, sampleType, fullSampleName, sampleInterval, sampleSize,
+                        sampleDescription, 1 );
+                    instrumentSample.enableLogging( getLogger() );
+                    instrumentSample.loadState( instrumentSampleConf );
+                    
+                    addInstrumentSample( instrumentSample );
+                    
+                    sample = instrumentSample;
                 }
                 else
                 {
-                    sample.loadState( instrumentSampleConf );
+                    // Permantent sample which no longer exists.
+                    getLogger().info( "InstrumentSample entry ignored while loading state " +
+                        "because the sample does not exist: " + fullSampleName );
                 }
             }
+            else
+            {
+                sample.loadState( instrumentSampleConf );
+            }
         }
         
-        stateChanged();
+        //  If the sample's state was changed then it will call stateChanged for the instrument
+        
+        return sample;
     }
     
     /**

Modified: excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentSample.java
URL: http://svn.apache.org/viewcvs/excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentSample.java?rev=279496&r1=279495&r2=279496&view=diff
==============================================================================
--- excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentSample.java (original)
+++ excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentSample.java Wed Sep  7 20:26:34 2005
@@ -191,18 +191,6 @@
     void removeInstrumentSampleListener( InstrumentSampleListener listener );
     
     /**
-     * Used to test whether or not any state information exists prior to
-     *  writeState() being called.  This process is not synchronized so it
-     *  is possible that the return value will no longer be accurate when
-     *  writeState is actually called.  For the purpose of writing the
-     *  state however this is accurate enough.
-     *
-     * @return True if state information exists which should be written to
-     *         a state file.
-     */
-    boolean hasState();
-    
-    /**
      * Writes the current state to a PrintWriter as XML.
      *
      * @param out The PrintWriter to which the state should be written.

Modified: excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentableProxy.java
URL: http://svn.apache.org/viewcvs/excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentableProxy.java?rev=279496&r1=279495&r2=279496&view=diff
==============================================================================
--- excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentableProxy.java (original)
+++ excalibur/trunk/containerkit/instrument/mgr-impl/src/java/org/apache/excalibur/instrument/manager/impl/InstrumentableProxy.java Wed Sep  7 20:26:34 2005
@@ -336,6 +336,48 @@
         
         stateChanged();
     }
+    
+    /**
+     *
+     */
+    InstrumentableProxy getChildInstrumentableProxy( String childInstrumentableName,
+                                                     boolean create )
+    {
+        synchronized( this )
+        {
+            InstrumentableProxy childInstrumentableProxy =
+                (InstrumentableProxy)m_childInstrumentableProxies.get( childInstrumentableName );
+            if ( ( childInstrumentableProxy == null ) && create )
+            {
+                //getLogger().debug( "     New Child Instrumentable" );
+                // Not found, create it.
+                int pos = childInstrumentableName.lastIndexOf( '.' );
+                String childName;
+                if ( pos >= 0 )
+                {
+                    childName = childInstrumentableName.substring( pos + 1 );
+                }
+                else
+                {
+                    childName = childInstrumentableName;
+                }
+                
+                childInstrumentableProxy = new InstrumentableProxy(
+                    m_instrumentManager, this, childInstrumentableName, childName );
+                childInstrumentableProxy.enableLogging( getLogger() );
+                m_instrumentManager.incrementInstrumentableCount();
+                m_childInstrumentableProxies.put(
+                    childInstrumentableName, childInstrumentableProxy );
+
+                // Clear the optimized arrays
+                m_childInstrumentableProxyArray = null;
+                m_childInstrumentableDescriptorArray = null;
+            }
+            
+            //getLogger().debug( "  -> " + childInstrumentableProxy );
+            return childInstrumentableProxy;
+        }
+    }
 
     /**
      * Returns a child InstrumentableProxy based on its name or the name of any
@@ -502,6 +544,45 @@
     }
 
     /**
+     *
+     */
+    InstrumentProxy getInstrumentProxy( String instrumentName, boolean create )
+    {
+        synchronized( this )
+        {
+            InstrumentProxy instrumentProxy =
+                (InstrumentProxy)m_instrumentProxies.get( instrumentName );
+            if ( ( instrumentProxy == null ) && create )
+            {
+                //getLogger().debug( "     New Instrument" );
+                // Not found, create it.
+                int pos = instrumentName.lastIndexOf( '.' );
+                String instName;
+                if ( pos >= 0 )
+                {
+                    instName = instrumentName.substring( pos + 1 );
+                }
+                else
+                {
+                    instName = instrumentName;
+                }
+                
+                instrumentProxy = new InstrumentProxy( this, instrumentName, instName );
+                instrumentProxy.enableLogging( getLogger() );
+                m_instrumentManager.incrementInstrumentCount();
+                m_instrumentProxies.put( instrumentName, instrumentProxy );
+
+                // Clear the optimized arrays
+                m_instrumentProxyArray = null;
+                m_instrumentDescriptorArray = null;
+            }
+            
+            //getLogger().debug( "  -> " + instrumentProxy );
+            return instrumentProxy;
+        }
+    }
+
+    /**
      * Returns a InstrumentProxy based on its name or the name of any
      *  of its children.
      *
@@ -641,151 +722,28 @@
     }
     
     /**
-     * Used to test whether or not any state information exists prior to
-     *  writeState() being called.  This process is not synchronized so it
-     *  is possible that the return value will no longer be accurate when
-     *  writeState is actually called.  For the purpose of writing the
-     *  state however this is accurate enough.
-     *
-     * @return True if state information exists which should be written to
-     *         a state file.
-     */
-    boolean hasState()
-    {
-        // Check instruments first as they are "closer".
-        InstrumentProxy[] proxies = getInstrumentProxies();
-        for( int i = 0; i < proxies.length; i++ )
-        {
-            InstrumentProxy instrument = proxies[i];
-            if ( instrument.hasState() )
-            {
-                return true;
-            }
-        }
-        
-        // Check child instrumentables.
-        InstrumentableProxy[] childProxies = getChildInstrumentableProxies();
-        for( int i = 0; i < childProxies.length; i++ )
-        {
-            InstrumentableProxy instrumentable = childProxies[i];
-            if ( instrumentable.hasState() )
-            {
-                return true;
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
      * Writes the current state to a PrintWriter as XML.
      *
      * @param out The PrintWriter to which the state should be written.
      */
     void writeState( PrintWriter out )
     {
-        // Open the node.
-        out.print( "<instrumentable name=\"" );
-        out.print( XMLUtil.getXMLSafeString( m_name ) );
-        out.println( "\">" );
+        // Samples are the only things written to the state, so all we need to do is drill down
+        //  to them.
         
         // Write out the states of any child instrumentables.
         InstrumentableProxy[] childProxies = getChildInstrumentableProxies();
         for( int i = 0; i < childProxies.length; i++ )
         {
-            InstrumentableProxy instrumentable = childProxies[i];
-            if ( instrumentable.hasState() )
-            {
-                instrumentable.writeState( out );
-            }
+            childProxies[i].writeState( out );
         }
         
         // Write out the states of any instruments.
         InstrumentProxy[] proxies = getInstrumentProxies();
         for( int i = 0; i < proxies.length; i++ )
         {
-            InstrumentProxy instrument = proxies[i];
-            if ( instrument.hasState() )
-            {
-                instrument.writeState( out );
-            }
-        }
-        
-        // Close the node.
-        out.println( "</instrumentable>" );
-    }
-
-    /**
-     * Loads the state into the Instrumentable.
-     *
-     * @param state Configuration object to load state from.
-     *
-     * @throws ConfigurationException If there were any problems loading the
-     *                                state.
-     */
-    void loadState( Configuration state ) throws ConfigurationException
-    {
-        synchronized( this )
-        {
-            // Load the child Instrumentables
-            Configuration[] childConfs = state.getChildren( "instrumentable" );
-            for( int i = 0; i < childConfs.length; i++ )
-            {
-                Configuration childConf = childConfs[ i ];
-                String fullChildName = childConf.getAttribute( "name" );
-                InstrumentableProxy childProxy = getChildInstrumentableProxy( fullChildName );
-                if( childProxy == null )
-                {
-                    // The child Instrumentable was in the state file, but has
-                    //  not yet been registered.  It is possible that it will
-                    //  be registered at a later time.  For now it needs to be
-                    //  created.
-                    String childName = ( fullChildName.startsWith( m_name + "." ) ?
-                        fullChildName.substring( m_name.length() + 1 ) : "BADNAME." + fullChildName );
-                    
-                    childProxy = new InstrumentableProxy(
-                        m_instrumentManager, this, fullChildName, childName );
-                    childProxy.enableLogging( getLogger() );
-                    m_instrumentManager.incrementInstrumentableCount();
-                    m_childInstrumentableProxies.put( fullChildName, childProxy );
-    
-                    // Clear the optimized arrays
-                    m_childInstrumentableProxyArray = null;
-                    m_childInstrumentableDescriptorArray = null;
-                }
-                childProxy.loadState( childConf );
-            }
-            
-            // Load the direct Instruments
-            Configuration[] instrumentConfs = state.getChildren( "instrument" );
-            for( int i = 0; i < instrumentConfs.length; i++ )
-            {
-                Configuration instrumentConf = instrumentConfs[ i ];
-                String fullInstrumentName = instrumentConf.getAttribute( "name" );
-                InstrumentProxy instrumentProxy = getInstrumentProxy( fullInstrumentName );
-                if( instrumentProxy == null )
-                {
-                    // The Instrument was in the state file, but has not yet been
-                    //  registered.  It is possible that it will be registered
-                    //  at a later time.  For now it needs to be created.
-                    String instrumentName = ( fullInstrumentName.startsWith( m_name + "." ) ?
-                        fullInstrumentName.substring( m_name.length() + 1 ) : "BADNAME." + fullInstrumentName );
-                    
-                    instrumentProxy =
-                        new InstrumentProxy( this, fullInstrumentName, instrumentName );
-                    instrumentProxy.enableLogging( getLogger() );
-                    m_instrumentManager.incrementInstrumentCount();
-                    m_instrumentProxies.put( fullInstrumentName, instrumentProxy );
-    
-                    // Clear the optimized arrays
-                    m_instrumentProxyArray = null;
-                    m_instrumentDescriptorArray = null;
-                }
-                instrumentProxy.loadState( instrumentConf );
-            }
+            proxies[i].writeState( out );
         }
-        
-        stateChanged();
     }
     
     /**



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