KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > instrument > manager > impl > InstrumentableProxy


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 package org.apache.excalibur.instrument.manager.impl;
21
22 import java.io.PrintWriter JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Comparator JavaDoc;
25 import java.util.HashMap JavaDoc;
26
27 import org.apache.avalon.framework.configuration.Configurable;
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.logger.AbstractLogEnabled;
31
32 import org.apache.excalibur.instrument.manager.InstrumentableDescriptor;
33 import org.apache.excalibur.instrument.manager.InstrumentDescriptor;
34
35 /**
36  * A InstrumentableProxy makes it easy for the InstrumentManager to manage
37  * Instrumentables and their Instruments.
38  * <p>
39  * Not Synchronized.
40  *
41  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
42  * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:25 $
43  * @since 4.1
44  */

45 class InstrumentableProxy
46     extends AbstractLogEnabled
47     implements Configurable
48 {
49     /** InstrumentManager which owns the proxy. */
50     private DefaultInstrumentManagerImpl m_instrumentManager;
51     
52     /** The parent Instrumentable proxy or null if this is a top level
53      * Instrumentable. */

54     private InstrumentableProxy m_parentInstrumentableProxy;
55     
56     /** Configured flag. */
57     private boolean m_configured;
58
59     /** Registered flag. */
60     private boolean m_registered;
61
62     /** The name used to identify a Instrumentable. */
63     private String JavaDoc m_name;
64
65     /** The description of the Instrumentable. */
66     private String JavaDoc m_description;
67
68     /** The Descriptor for the Instrumentable. */
69     private InstrumentableDescriptorImpl m_descriptor;
70
71     /** Map of the Child InstrumentableProxies owned by this InstrumentableProxy. */
72     private HashMap JavaDoc m_childInstrumentableProxies = new HashMap JavaDoc();
73
74     /** Optimized array of the child InstrumentableProxies. */
75     private InstrumentableProxy[] m_childInstrumentableProxyArray;
76
77     /** Optimized array of the child InstrumentableDescriptors. */
78     private InstrumentableDescriptor[] m_childInstrumentableDescriptorArray;
79
80     /** Map of the InstrumentProxies owned by this InstrumentableProxy. */
81     private HashMap JavaDoc m_instrumentProxies = new HashMap JavaDoc();
82
83     /** Optimized array of the InstrumentProxies. */
84     private InstrumentProxy[] m_instrumentProxyArray;
85
86     /** Optimized array of the InstrumentDescriptors. */
87     private InstrumentDescriptor[] m_instrumentDescriptorArray;
88     
89     /** State Version. */
90     private int m_stateVersion;
91
92     /*---------------------------------------------------------------
93      * Constructors
94      *-------------------------------------------------------------*/

95     /**
96      * Creates a new InstrumentableProxy.
97      *
98      * @param instrumentManager InstrumentManager which owns the proxy.
99      * @param parentInstrumentableProxy The parent Instrumentable proxy or null
100      * if this is a top level Instrumentable.
101      * @param name The name used to identify a Instrumentable.
102      * @param description The description of the the Instrumentable.
103      */

104     InstrumentableProxy( DefaultInstrumentManagerImpl instrumentManager,
105                          InstrumentableProxy parentInstrumentableProxy,
106                          String JavaDoc name,
107                          String JavaDoc description )
108     {
109         m_instrumentManager = instrumentManager;
110         m_parentInstrumentableProxy = parentInstrumentableProxy;
111         m_name = name;
112         m_description = description;
113
114         // Create the descriptor
115
m_descriptor = new InstrumentableDescriptorImpl( this );
116     }
117
118     /*---------------------------------------------------------------
119      * Configurable Methods
120      *-------------------------------------------------------------*/

121     /**
122      * Configures the Instrumentable. Called from the InstrumentManager's
123      * configure method. The class does not need to be configured to
124      * function correctly.
125      *
126      * @param configuration Instrumentable configuration element from the
127      * InstrumentManager's configuration.
128      *
129      * @throws ConfigurationException If there are any configuration problems.
130      */

131     public void configure( Configuration configuration )
132         throws ConfigurationException
133     {
134         synchronized( this )
135         {
136             // The description is optional. Default to the description from the constructor.
137
m_description = configuration.getAttribute( "description", m_description );
138
139             if( getLogger().isDebugEnabled() )
140             {
141                 getLogger().debug( "Configuring Instrumentable: " + m_name + " as \"" +
142                                    m_description + "\"" );
143             }
144
145             m_configured = true;
146             
147             // Configure any child Instrumentables
148
Configuration[] childConfs = configuration.getChildren( "instrumentable" );
149             for( int i = 0; i < childConfs.length; i++ )
150             {
151                 Configuration childConf = childConfs[ i ];
152                 String JavaDoc childName = childConf.getAttribute( "name" );
153                 String JavaDoc fullChildName = m_name + "." + childName;
154                 
155                 // See if the instrumentable already exists.
156
InstrumentableProxy childProxy = getChildInstrumentableProxy( fullChildName );
157                 if( childProxy == null )
158                 {
159                     childProxy = new InstrumentableProxy(
160                         m_instrumentManager, this, fullChildName, childName );
161                     childProxy.enableLogging( getLogger() );
162                     m_instrumentManager.incrementInstrumentableCount();
163                     m_childInstrumentableProxies.put( fullChildName, childProxy );
164     
165                     // Clear the optimized arrays
166
m_childInstrumentableProxyArray = null;
167                     m_childInstrumentableDescriptorArray = null;
168                 }
169                 // Always configure the instrumentable.
170
childProxy.configure( childConf );
171             }
172             
173             // Configure any Instruments
174
Configuration[] instrumentConfs = configuration.getChildren( "instrument" );
175             for( int i = 0; i < instrumentConfs.length; i++ )
176             {
177                 Configuration instrumentConf = instrumentConfs[ i ];
178                 String JavaDoc instrumentName = instrumentConf.getAttribute( "name" );
179                 String JavaDoc fullInstrumentName = m_name + "." + instrumentName;
180
181                 // See if the instrument already exists.
182
InstrumentProxy instrumentProxy = getInstrumentProxy( fullInstrumentName );
183                 if ( instrumentProxy == null )
184                 {
185                     instrumentProxy =
186                         new InstrumentProxy( this, fullInstrumentName, instrumentName );
187                     instrumentProxy.enableLogging( getLogger() );
188                     m_instrumentManager.incrementInstrumentCount();
189                     m_instrumentProxies.put( fullInstrumentName, instrumentProxy );
190     
191                     // Clear the optimized arrays
192
m_instrumentProxyArray = null;
193                     m_instrumentDescriptorArray = null;
194                 }
195                 // Always configure the instrument
196
instrumentProxy.configure( instrumentConf );
197             }
198         }
199     }
200
201     /*---------------------------------------------------------------
202      * Methods
203      *-------------------------------------------------------------*/

204     /**
205      * Returns instrumentManager which owns the proxy.
206      *
207      * @return InstrumentManager which owns the proxy.
208      */

209     DefaultInstrumentManagerImpl getInstrumentManager()
210     {
211         return m_instrumentManager;
212     }
213     
214     /**
215      * Returns the parent InstrumentableProxy or null if this is a top level
216      * proxy.
217      *
218      * @return The parent InstrumentableProxy or null.
219      */

220     InstrumentableProxy getParentInstrumentableProxy()
221     {
222         return m_parentInstrumentableProxy;
223     }
224     
225     /**
226      * Returns true if the instrumentable was configured in the instrumentables
227      * section of the configuration.
228      *
229      * @return True if configured.
230      */

231     boolean isConfigured()
232     {
233         return m_configured;
234     }
235
236     /**
237      * Returns true if the Instrumentable was registered with the Instrument
238      * Manager.
239      *
240      * @return True if registered.
241      */

242     boolean isRegistered()
243     {
244         return m_registered;
245     }
246     
247     /**
248      * Called by the InstrumentManager whenever an Instrumentable assigned to
249      * this proxy is registered.
250      */

251     void setRegistered()
252     {
253         if ( !m_registered )
254         {
255             m_registered = true;
256             stateChanged();
257         }
258     }
259     
260     /**
261      * Gets the name for the Instrumentable. The Instrumentable Name is used
262      * to uniquely identify the Instrumentable during its configuration and to
263      * gain access to a InstrumentableDescriptor through an InstrumentManager.
264      *
265      * @return The name used to identify a Instrumentable.
266      */

267     String JavaDoc getName()
268     {
269         return m_name;
270     }
271
272     /**
273      * Sets the description for the instrumentable object. This description will
274      * be set during the configuration of the Instrumentable if a configuration
275      * exists.
276      *
277      * @param description The description of the Instrumentable.
278      */

279     void setDescription( String JavaDoc description )
280     {
281         String JavaDoc oldDescription = m_description; // thread safety.
282
if ( ( oldDescription == description ) || ( ( description != null ) && description.equals( oldDescription ) ) )
283         {
284             // No change
285
}
286         else
287         {
288             m_description = description;
289             stateChanged();
290         }
291     }
292
293     /**
294      * Gets the description of the Instrumentable.
295      *
296      * @return The description of the Instrumentable.
297      */

298     String JavaDoc getDescription()
299     {
300         return m_description;
301     }
302
303     /**
304      * Returns a Descriptor for the Instrumentable.
305      *
306      * @return A Descriptor for the Instrumentable.
307      */

308     InstrumentableDescriptor getDescriptor()
309     {
310         return m_descriptor;
311     }
312
313     /*---------------------------------------------------------------
314      * Methods (child Instrumentables)
315      *-------------------------------------------------------------*/

316     /**
317      * Adds a child InstrumentableProxy to the Instrumentable. This method
318      * will be called during the configuration phase if an element defining
319      * the child Instrumentable exists, or if the Instrumentable registers
320      * itself with the InstrumentManager as it is running.
321      * <p>
322      * This method should never be called for child Instrumentables which
323      * have already been added.
324      *
325      * @param childInstrumentableProxy Child InstrumentableProxy to be added.
326      */

327     void addChildInstrumentableProxy( InstrumentableProxy childInstrumentableProxy )
328     {
329         synchronized( this )
330         {
331             m_childInstrumentableProxies.put(
332                 childInstrumentableProxy.getName(), childInstrumentableProxy );
333
334             // Clear the optimized arrays
335
m_childInstrumentableProxyArray = null;
336             m_childInstrumentableDescriptorArray = null;
337         }
338         
339         stateChanged();
340     }
341     
342     /**
343      *
344      */

345     InstrumentableProxy getChildInstrumentableProxy( String JavaDoc childInstrumentableName,
346                                                      boolean create )
347     {
348         synchronized( this )
349         {
350             InstrumentableProxy childInstrumentableProxy =
351                 (InstrumentableProxy)m_childInstrumentableProxies.get( childInstrumentableName );
352             if ( ( childInstrumentableProxy == null ) && create )
353             {
354                 //getLogger().debug( " New Child Instrumentable" );
355
// Not found, create it.
356
int pos = childInstrumentableName.lastIndexOf( '.' );
357                 String JavaDoc childName;
358                 if ( pos >= 0 )
359                 {
360                     childName = childInstrumentableName.substring( pos + 1 );
361                 }
362                 else
363                 {
364                     childName = childInstrumentableName;
365                 }
366                 
367                 childInstrumentableProxy = new InstrumentableProxy(
368                     m_instrumentManager, this, childInstrumentableName, childName );
369                 childInstrumentableProxy.enableLogging( getLogger() );
370                 m_instrumentManager.incrementInstrumentableCount();
371                 m_childInstrumentableProxies.put(
372                     childInstrumentableName, childInstrumentableProxy );
373
374                 // Clear the optimized arrays
375
m_childInstrumentableProxyArray = null;
376                 m_childInstrumentableDescriptorArray = null;
377             }
378             
379             //getLogger().debug( " -> " + childInstrumentableProxy );
380
return childInstrumentableProxy;
381         }
382     }
383
384     /**
385      * Returns a child InstrumentableProxy based on its name or the name of any
386      * of its children.
387      *
388      * @param childInstrumentableName Name of the child Instrumentable being
389      * requested.
390      *
391      * @return The requested child InstrumentableProxy or null if does not
392      * exist.
393      */

394     InstrumentableProxy getChildInstrumentableProxy( String JavaDoc childInstrumentableName )
395     {
396         synchronized( this )
397         {
398             String JavaDoc name = childInstrumentableName;
399             while( true )
400             {
401                 InstrumentableProxy proxy =
402                     (InstrumentableProxy)m_childInstrumentableProxies.get( name );
403                 if( proxy != null )
404                 {
405                     return proxy;
406                 }
407
408                 // Assume this is a child name and try looking with the parent name.
409
int pos = name.lastIndexOf( '.' );
410                 if( pos > 0 )
411                 {
412                     name = name.substring( 0, pos );
413                 }
414                 else
415                 {
416                     return null;
417                 }
418             }
419         }
420     }
421
422     /**
423      * Returns an array of Proxies to the child Instrumentables in this
424      * Instrumentable.
425      *
426      * @return An array of Proxies to the child Instrumentables in this
427      * Instrumentable.
428      */

429     InstrumentableProxy[] getChildInstrumentableProxies()
430     {
431         InstrumentableProxy[] proxies = m_childInstrumentableProxyArray;
432         if( proxies == null )
433         {
434             proxies = updateChildInstrumentableProxyArray();
435         }
436         
437         return proxies;
438     }
439
440     /**
441      * Returns an array of Descriptors for the child Instrumentables in this
442      * Instrumentable.
443      *
444      * @return An array of Descriptors for the child Instrumentables in this
445      * Instrumentable.
446      */

447     InstrumentableDescriptor[] getChildInstrumentableDescriptors()
448     {
449         InstrumentableDescriptor[] descriptors = m_childInstrumentableDescriptorArray;
450         if( descriptors == null )
451         {
452             descriptors = updateChildInstrumentableDescriptorArray();
453         }
454         
455         return descriptors;
456     }
457
458     /**
459      * Updates the cached array of child InstrumentableProxies taking
460      * synchronization into account.
461      *
462      * @return An array of the child InstrumentableProxies.
463      */

464     private InstrumentableProxy[] updateChildInstrumentableProxyArray()
465     {
466         synchronized( this )
467         {
468             InstrumentableProxy[] childInstrumentableProxyArray =
469                 new InstrumentableProxy[ m_childInstrumentableProxies.size() ];
470             m_childInstrumentableProxies.values().toArray( childInstrumentableProxyArray );
471
472             // Sort the array. This is not a performance problem because this
473
// method is rarely called and doing it here saves cycles in the
474
// client.
475
Arrays.sort( childInstrumentableProxyArray, new Comparator JavaDoc()
476                 {
477                     public int compare( Object JavaDoc o1, Object JavaDoc o2 )
478                     {
479                         return ((InstrumentableProxy)o1).getDescription().
480                             compareTo( ((InstrumentableProxy)o2).getDescription() );
481                     }
482                     
483                     public boolean equals( Object JavaDoc obj )
484                     {
485                         return false;
486                     }
487                 } );
488             
489             // Once we are done modifying this array, set it to the variable accessable outside
490
// of synchronization.
491
m_childInstrumentableProxyArray = childInstrumentableProxyArray;
492             
493             return childInstrumentableProxyArray;
494         }
495     }
496
497     /**
498      * Updates the cached array of child InstrumentableDescriptors taking
499      * synchronization into account.
500      *
501      * @return An array of the child InstrumentableDescriptors.
502      */

503     private InstrumentableDescriptor[] updateChildInstrumentableDescriptorArray()
504     {
505         synchronized( this )
506         {
507             // Get the proxy array. This is done in synchronization so it is not possible that it
508
// will be reset before we obtain the descriptor array. They are both set to null
509
// at the same time when there is a change.
510
InstrumentableProxy[] childInstrumentableProxyArray = m_childInstrumentableProxyArray;
511             if( childInstrumentableProxyArray == null )
512             {
513                 childInstrumentableProxyArray = updateChildInstrumentableProxyArray();
514             }
515
516             InstrumentableDescriptor[] childInstrumentableDescriptorArray =
517                 new InstrumentableDescriptor[ childInstrumentableProxyArray.length ];
518             for( int i = 0; i < childInstrumentableProxyArray.length; i++ )
519             {
520                 childInstrumentableDescriptorArray[ i ] =
521                     childInstrumentableProxyArray[ i ].getDescriptor();
522             }
523
524             // Once we are done modifying this array, set it to the variable accessable outside
525
// of synchronization.
526
m_childInstrumentableDescriptorArray = childInstrumentableDescriptorArray;
527             
528             return childInstrumentableDescriptorArray;
529         }
530     }
531
532     /*---------------------------------------------------------------
533      * Methods (Instruments)
534      *-------------------------------------------------------------*/

535     /**
536      * Adds a InstrumentProxy to the Instrumentable. This method will be
537      * called during the configuration phase if an element defining the
538      * Instrument exists, or if the Instrument registers itself with the
539      * InstrumentManager as it is running.
540      * <p>
541      * This method should never be called for Instruments which have already
542      * been added.
543      *
544      * @param instrumentProxy InstrumentProxy to be added.
545      */

546     void addInstrumentProxy( InstrumentProxy instrumentProxy )
547     {
548         synchronized( this )
549         {
550             m_instrumentProxies.put( instrumentProxy.getName(), instrumentProxy );
551
552             // Clear the optimized arrays
553
m_instrumentProxyArray = null;
554             m_instrumentDescriptorArray = null;
555         }
556         
557         stateChanged();
558     }
559
560     /**
561      *
562      */

563     InstrumentProxy getInstrumentProxy( String JavaDoc instrumentName, boolean create )
564     {
565         synchronized( this )
566         {
567             InstrumentProxy instrumentProxy =
568                 (InstrumentProxy)m_instrumentProxies.get( instrumentName );
569             if ( ( instrumentProxy == null ) && create )
570             {
571                 //getLogger().debug( " New Instrument" );
572
// Not found, create it.
573
int pos = instrumentName.lastIndexOf( '.' );
574                 String JavaDoc instName;
575                 if ( pos >= 0 )
576                 {
577                     instName = instrumentName.substring( pos + 1 );
578                 }
579                 else
580                 {
581                     instName = instrumentName;
582                 }
583                 
584                 instrumentProxy = new InstrumentProxy( this, instrumentName, instName );
585                 instrumentProxy.enableLogging( getLogger() );
586                 m_instrumentManager.incrementInstrumentCount();
587                 m_instrumentProxies.put( instrumentName, instrumentProxy );
588
589                 // Clear the optimized arrays
590
m_instrumentProxyArray = null;
591                 m_instrumentDescriptorArray = null;
592             }
593             
594             //getLogger().debug( " -> " + instrumentProxy );
595
return instrumentProxy;
596         }
597     }
598
599     /**
600      * Returns a InstrumentProxy based on its name or the name of any
601      * of its children.
602      *
603      * @param instrumentName Name of the Instrument being requested.
604      *
605      * @return The requested InstrumentProxy or null if does not exist.
606      */

607     InstrumentProxy getInstrumentProxy( String JavaDoc instrumentName )
608     {
609         synchronized( this )
610         {
611             String JavaDoc name = instrumentName;
612             while( true )
613             {
614                 InstrumentProxy proxy = (InstrumentProxy)m_instrumentProxies.get( name );
615                 if( proxy != null )
616                 {
617                     return proxy;
618                 }
619
620                 // Assume this is a child name and try looking with the parent name.
621
int pos = name.lastIndexOf( '.' );
622                 if( pos > 0 )
623                 {
624                     name = name.substring( 0, pos );
625                 }
626                 else
627                 {
628                     return null;
629                 }
630             }
631         }
632     }
633
634     /**
635      * Returns an array of Proxies to the Instruments in the Instrumentable.
636      *
637      * @return An array of Proxies to the Instruments in the Instrumentable.
638      */

639     InstrumentProxy[] getInstrumentProxies()
640     {
641         InstrumentProxy[] proxies = m_instrumentProxyArray;
642         if( proxies == null )
643         {
644             proxies = updateInstrumentProxyArray();
645         }
646         return proxies;
647     }
648
649     /**
650      * Returns an array of Descriptors for the Instruments in the Instrumentable.
651      *
652      * @return An array of Descriptors for the Instruments in the Instrumentable.
653      */

654     InstrumentDescriptor[] getInstrumentDescriptors()
655     {
656         InstrumentDescriptor[] descriptors = m_instrumentDescriptorArray;
657         if( descriptors == null )
658         {
659             descriptors = updateInstrumentDescriptorArray();
660         }
661         return descriptors;
662     }
663     
664     /**
665      * Returns the stateVersion of the instrumentable. The state version
666      * will be incremented each time any of the configuration of the
667      * instrumentable or any of its children is modified.
668      * Clients can use this value to tell whether or not anything has
669      * changed without having to do an exhaustive comparison.
670      *
671      * @return The state version of the instrumentable.
672      */

673     int getStateVersion()
674     {
675         return m_stateVersion;
676     }
677
678     /**
679      * Updates the cached array of InstrumentProxies taking
680      * synchronization into account.
681      *
682      * @return An array of the InstrumentProxies.
683      */

684     private InstrumentProxy[] updateInstrumentProxyArray()
685     {
686         synchronized( this )
687         {
688             InstrumentProxy[] instrumentProxyArray =
689                 new InstrumentProxy[ m_instrumentProxies.size() ];
690             m_instrumentProxies.values().toArray( instrumentProxyArray );
691
692             // Sort the array. This is not a performance problem because this
693
// method is rarely called and doing it here saves cycles in the
694
// client.
695
Arrays.sort( instrumentProxyArray, new Comparator JavaDoc()
696                 {
697                     public int compare( Object JavaDoc o1, Object JavaDoc o2 )
698                     {
699                         return ((InstrumentProxy)o1).getDescription().
700                             compareTo( ((InstrumentProxy)o2).getDescription() );
701                     }
702                     
703                     public boolean equals( Object JavaDoc obj )
704                     {
705                         return false;
706                     }
707                 } );
708             
709             // Once we are done modifying this array, set it to the variable accessable outside
710
// of synchronization.
711
m_instrumentProxyArray = instrumentProxyArray;
712             
713             return instrumentProxyArray;
714         }
715     }
716
717     /**
718      * Updates the cached array of InstrumentDescriptors taking
719      * synchronization into account.
720      *
721      * @return An array of the InstrumentDescriptors.
722      */

723     private InstrumentDescriptor[] updateInstrumentDescriptorArray()
724     {
725         synchronized( this )
726         {
727             // Get the proxy array. This is done in synchronization so it is not possible that it
728
// will be reset before we obtain the descriptor array. They are both set to null
729
// at the same time when there is a change.
730
InstrumentProxy[] instrumentProxyArray = m_instrumentProxyArray;
731             if( instrumentProxyArray == null )
732             {
733                 instrumentProxyArray = updateInstrumentProxyArray();
734             }
735             
736             InstrumentDescriptor[] instrumentDescriptorArray =
737                 new InstrumentDescriptor[ instrumentProxyArray.length ];
738             for( int i = 0; i < instrumentProxyArray.length; i++ )
739             {
740                 instrumentDescriptorArray[ i ] = instrumentProxyArray[ i ].getDescriptor();
741             }
742             
743             // Once we are done modifying this array, set it to the variable accessable outside
744
// of synchronization.
745
m_instrumentDescriptorArray = instrumentDescriptorArray;
746             
747             return instrumentDescriptorArray;
748         }
749     }
750     
751     /**
752      * Writes the current state to a PrintWriter as XML.
753      *
754      * @param out The PrintWriter to which the state should be written.
755      */

756     void writeState( PrintWriter JavaDoc out )
757     {
758         // Samples are the only things written to the state, so all we need to do is drill down
759
// to them.
760

761         // Write out the states of any child instrumentables.
762
InstrumentableProxy[] childProxies = getChildInstrumentableProxies();
763         for( int i = 0; i < childProxies.length; i++ )
764         {
765             childProxies[i].writeState( out );
766         }
767         
768         // Write out the states of any instruments.
769
InstrumentProxy[] proxies = getInstrumentProxies();
770         for( int i = 0; i < proxies.length; i++ )
771         {
772             proxies[i].writeState( out );
773         }
774     }
775     
776     /**
777      * Called whenever the state of the instrumentable is changed.
778      */

779     protected void stateChanged()
780     {
781         m_stateVersion++;
782         
783         // Propagate to the parent
784
if ( m_parentInstrumentableProxy == null )
785         {
786             // This is a top level Instrumentable
787
m_instrumentManager.stateChanged();
788         }
789         else
790         {
791             m_parentInstrumentableProxy.stateChanged();
792         }
793     }
794 }
795
Popular Tags