KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > instrument > client > InstrumentManagerTreeModel


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.client;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24
25 import javax.swing.event.TreeModelEvent JavaDoc;
26 import javax.swing.event.TreeModelListener JavaDoc;
27 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
28 import javax.swing.tree.TreeModel JavaDoc;
29 import javax.swing.tree.TreePath JavaDoc;
30
31 import org.apache.avalon.framework.logger.AbstractLogEnabled;
32
33 /**
34  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
35  */

36 class InstrumentManagerTreeModel
37     extends AbstractLogEnabled
38     implements InstrumentManagerConnectionListener, TreeModel JavaDoc
39 {
40     private final InstrumentManagerConnection m_connection;
41
42     /** The state version of the last client. */
43     private int m_lastClientStateVersion;
44     
45     private boolean m_lastConnected = false;
46
47     private DefaultMutableTreeNode JavaDoc m_root;
48
49     private ArrayList JavaDoc m_listeners = new ArrayList JavaDoc();
50     private TreeModelListener JavaDoc[] m_listenerArray;
51
52     private HashMap JavaDoc m_elementMap = new HashMap JavaDoc();
53     private HashMap JavaDoc m_leasedSampleMap = new HashMap JavaDoc();
54     private DefaultMutableTreeNode JavaDoc[] m_leasedSampleArray;
55
56     /*---------------------------------------------------------------
57      * Constructors
58      *-------------------------------------------------------------*/

59     InstrumentManagerTreeModel( InstrumentManagerConnection connection )
60     {
61         m_connection = connection;
62
63         m_root = new DefaultMutableTreeNode JavaDoc( "Root" );
64     }
65
66     /*---------------------------------------------------------------
67      * InstrumentManagerConnectionListener Methods
68      *-------------------------------------------------------------*/

69     /**
70      * Called when the connection is opened. May be called more than once if
71      * the connection to the InstrumentManager is reopened.
72      *
73      * @param connection Connection which was opened.
74      */

75     public void opened( InstrumentManagerConnection connection )
76     {
77         getLogger().debug( "InstrumentManagerTreeModel.opened(" + connection + ")" );
78         refreshModel();
79     }
80
81     /**
82      * Called when the connection is closed. May be called more than once if
83      * the connection to the InstrumentManager is reopened.
84      *
85      * @param connection Connection which was closed.
86      */

87     public void closed( InstrumentManagerConnection connection )
88     {
89         getLogger().debug( "InstrumentManagerTreeModel.closed(" + connection + ")" );
90         refreshModel();
91     }
92
93     /**
94      * Called when the connection is deleted. All references should be removed.
95      *
96      * @param connection Connection which was deleted.
97      */

98     public void deleted( InstrumentManagerConnection connection )
99     {
100         getLogger().debug( "InstrumentManagerTreeModel.deleted(" + connection + ")" );
101         refreshModel();
102     }
103
104     /*---------------------------------------------------------------
105      * TreeModel Methods
106      *-------------------------------------------------------------*/

107     /**
108      * Returns the root of the tree. Returns null only if the tree has
109      * no nodes.
110      *
111      * @return the root of the tree
112      */

113     public Object JavaDoc getRoot()
114     {
115         return m_root;
116     }
117
118     /**
119      * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
120      * child array. <I>parent</I> must be a node previously obtained from
121      * this data source. This should not return null if <i>index</i>
122      * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&
123      * <i>index</i> < getChildCount(<i>parent</i>)).
124      *
125      * @param parent a node in the tree, obtained from this data source
126      * @return the child of <I>parent</I> at index <I>index</I>
127      */

128     public Object JavaDoc getChild( Object JavaDoc parent, int index )
129     {
130         //getLogger.debug("InstrumentManagerTreeModel.getChild(" + parent + ", " + index + ")");
131
if ( parent instanceof DefaultMutableTreeNode JavaDoc )
132         {
133             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)parent;
134             return node.getChildAt( index );
135         }
136         else
137         {
138             return "---";
139         }
140     }
141
142
143     /**
144      * Returns the number of children of <I>parent</I>. Returns 0 if the node
145      * is a leaf or if it has no children. <I>parent</I> must be a node
146      * previously obtained from this data source.
147      *
148      * @param parent a node in the tree, obtained from this data source
149      * @return the number of children of the node <I>parent</I>
150      */

151     public int getChildCount( Object JavaDoc parent )
152     {
153         //getLogger.debug("InstrumentManagerTreeModel.getChildCount(" + parent + ")");
154
if ( parent instanceof DefaultMutableTreeNode JavaDoc )
155         {
156             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)parent;
157             return node.getChildCount();
158         }
159         else
160         {
161             return 0;
162         }
163     }
164
165     /**
166      * Returns true if <I>node</I> is a leaf. It is possible for this method
167      * to return false even if <I>node</I> has no children. A directory in a
168      * filesystem, for example, may contain no files; the node representing
169      * the directory is not a leaf, but it also has no children.
170      *
171      * @param node a node in the tree, obtained from this data source
172      * @return true if <I>node</I> is a leaf
173      */

174     public boolean isLeaf( Object JavaDoc node )
175     {
176         //getLogger.debug("InstrumentManagerTreeModel.isLeaf(" + node + ")");
177
if ( node == m_root )
178         {
179             // The root must always return false so that trees that do not
180
// show their root node will display correctly.
181
return false;
182         }
183         else if ( node instanceof DefaultMutableTreeNode JavaDoc )
184         {
185             DefaultMutableTreeNode JavaDoc inode = (DefaultMutableTreeNode JavaDoc)node;
186             return inode.isLeaf();
187         }
188         else
189         {
190             return true;
191         }
192     }
193
194     /**
195      * Messaged when the user has altered the value for the item identified
196      * by <I>path</I> to <I>newValue</I>. If <I>newValue</I> signifies
197      * a truly new value the model should post a treeNodesChanged
198      * event.
199      *
200      * @param path path to the node that the user has altered.
201      * @param newValue the new value from the TreeCellEditor.
202      */

203     public void valueForPathChanged( TreePath JavaDoc path, Object JavaDoc newValue )
204     {
205         //getLogger.debug( "InstrumentManagerTreeModel.valueForPathChanged(" + path +
206
// ", " + newValue + ")" );
207
}
208
209     /**
210      * Returns the index of child in parent.
211      */

212     public int getIndexOfChild( Object JavaDoc parent, Object JavaDoc child )
213     {
214         //getLogger.debug("InstrumentManagerTreeModel.getIndexOfChild(" + parent + ", " + child + ")");
215
if ( parent instanceof DefaultMutableTreeNode JavaDoc )
216         {
217             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)parent;
218             return node.getIndex( (DefaultMutableTreeNode JavaDoc)child );
219         }
220         else
221         {
222             return 0;
223         }
224     }
225
226     /**
227      * Adds a listener for the TreeModelEvent posted after the tree changes.
228      *
229      * @param listener the listener to add
230      */

231     public void addTreeModelListener( TreeModelListener JavaDoc listener )
232     {
233         //getLogger.debug("InstrumentManagerTreeModel.addTreeModelListener(" + listener + ")");
234
synchronized(this)
235         {
236             m_listeners.add( listener );
237             m_listenerArray = null;
238         }
239     }
240
241     /**
242      * Removes a listener previously added with <B>addTreeModelListener()</B>.
243      *
244      * @param listener the listener to remove
245      */

246     public void removeTreeModelListener( TreeModelListener JavaDoc listener )
247     {
248         //getLogger.debug("InstrumentManagerTreeModel.removeTreeModelListener(" + listener + ")");
249
synchronized(this)
250         {
251             m_listeners.remove( listener );
252             m_listenerArray = null;
253         }
254     }
255
256
257     /*---------------------------------------------------------------
258      * Methods
259      *-------------------------------------------------------------*/

260     /**
261      * Returns an optimized array of the registered TreeModelListeners.
262      *
263      * @return An array of the registered TreeModelListeners
264      */

265     private TreeModelListener JavaDoc[] getListeners()
266     {
267         TreeModelListener JavaDoc[] listeners = m_listenerArray;
268         if ( listeners == null )
269         {
270             synchronized(this)
271             {
272                 m_listenerArray = new TreeModelListener JavaDoc[ m_listeners.size() ];
273                 m_listeners.toArray( m_listenerArray );
274                 listeners = m_listenerArray;
275             }
276         }
277         return listeners;
278     }
279
280     private void fireTreeNodesChanged( TreeModelEvent JavaDoc event )
281     {
282         TreeModelListener JavaDoc[] listeners = getListeners();
283         for ( int i = 0; i < listeners.length; i++ )
284         {
285             listeners[i].treeNodesChanged( event );
286         }
287     }
288
289     private void fireTreeNodesInserted( TreeModelEvent JavaDoc event )
290     {
291         TreeModelListener JavaDoc[] listeners = getListeners();
292         for ( int i = 0; i < listeners.length; i++ )
293         {
294             listeners[i].treeNodesInserted( event );
295         }
296     }
297
298     private void fireTreeNodesRemoved( TreeModelEvent JavaDoc event )
299     {
300         TreeModelListener JavaDoc[] listeners = getListeners();
301         for ( int i = 0; i < listeners.length; i++ )
302         {
303             listeners[i].treeNodesRemoved( event );
304         }
305     }
306
307     private void fireTreeStructureChanged( TreeModelEvent JavaDoc event )
308     {
309         TreeModelListener JavaDoc[] listeners = getListeners();
310         for ( int i = 0; i < listeners.length; i++ )
311         {
312             listeners[i].treeStructureChanged( event );
313         }
314     }
315
316     /**
317      * Returns a TreeNode for an Instrumentable given its name.
318      *
319      * @param name Name of the Instrumentable.
320      *
321      * @return The named TreeNode.
322      */

323     public DefaultMutableTreeNode JavaDoc getInstrumentableTreeNode( String JavaDoc name )
324     {
325         DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)m_elementMap.get( name );
326         if ( node != null )
327         {
328             Object JavaDoc element = node.getUserObject();
329             if ( element instanceof InstrumentableNodeData )
330             {
331                 return node;
332             }
333         }
334         return null;
335     }
336
337     /**
338      * Returns a TreeNode for an Instrument given its name.
339      *
340      * @param name Name of the Instrument.
341      *
342      * @return The named TreeNode.
343      */

344     public DefaultMutableTreeNode JavaDoc getInstrumentTreeNode( String JavaDoc name )
345     {
346         DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)m_elementMap.get( name );
347         if ( node != null )
348         {
349             Object JavaDoc element = node.getUserObject();
350             if ( element instanceof InstrumentNodeData )
351             {
352                 return node;
353             }
354         }
355         return null;
356     }
357
358     /**
359      * Returns a TreeNode for an InstrumentSample given its name.
360      *
361      * @param name Name of the InstrumentSample.
362      *
363      * @return The named TreeNode.
364      */

365     public DefaultMutableTreeNode JavaDoc getInstrumentSampleTreeNode( String JavaDoc name )
366     {
367         DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)m_elementMap.get( name );
368         if ( node != null )
369         {
370             Object JavaDoc element = node.getUserObject();
371             if ( element instanceof InstrumentSampleNodeData )
372             {
373                 return node;
374             }
375         }
376         return null;
377     }
378
379     /**
380      * Returns an optimized array of TreeNodes representing the leased
381      * instrument samples in this tree model.
382      *
383      * @return An array of TreeNodes for the leased instrument samples
384      * in the TreeModel.
385      */

386     private DefaultMutableTreeNode JavaDoc[] getLeasedSampleArray()
387     {
388         DefaultMutableTreeNode JavaDoc[] leasedSampleArray = m_leasedSampleArray;
389         if ( leasedSampleArray == null )
390         {
391             synchronized(this)
392             {
393                 m_leasedSampleArray = new DefaultMutableTreeNode JavaDoc[ m_leasedSampleMap.size() ];
394                 m_leasedSampleMap.values().toArray( m_leasedSampleArray );
395                 leasedSampleArray = m_leasedSampleArray;
396             }
397         }
398         return leasedSampleArray;
399     }
400
401     /**
402      * Once a minute, all of the leased samples should be updated. This is
403      * necessary to get the latest expiration times in case other processes
404      * are also updating the leases.
405      * Called from InstrumentManagerConnection.handleLeasedSamples.
406      */

407     void renewAllSampleLeases()
408     {
409         DefaultMutableTreeNode JavaDoc[] leasedSampleArray = getLeasedSampleArray();
410
411         for ( int i = 0; i < leasedSampleArray.length; i++ )
412         {
413             // Extract the NodeData from the TreeNode
414
InstrumentSampleNodeData sampleNodeData =
415                 (InstrumentSampleNodeData)leasedSampleArray[i].getUserObject();
416             InstrumentSampleData sample = sampleNodeData.getData();
417
418             updateInstrumentSample( sample );
419         }
420     }
421
422     /**
423      * Remove any instrument samples whose current leases have expired.
424      */

425     void purgeExpiredSamples()
426     {
427         DefaultMutableTreeNode JavaDoc[] leasedSampleArray = getLeasedSampleArray();
428
429         for ( int i = 0; i < leasedSampleArray.length; i++ )
430         {
431             // Extract the NodeData from the TreeNode
432
InstrumentSampleNodeData sampleNodeData =
433                 (InstrumentSampleNodeData)leasedSampleArray[i].getUserObject();
434             //System.out.println(" check: " + sampleNodeData + " remaining " +
435
// ( sampleNodeData.getRemainingLeaseTime() / 1000 ) + " seconds." );
436
if ( sampleNodeData.getRemainingLeaseTime() < 0 )
437             {
438                 // Update the Instrument containing the sample.
439
DefaultMutableTreeNode JavaDoc instrumentTreeNode =
440                     (DefaultMutableTreeNode JavaDoc)leasedSampleArray[i].getParent();
441                 InstrumentData instrumentData =
442                     ((InstrumentNodeData)instrumentTreeNode.getUserObject()).getData();
443                 updateInstrument( instrumentData, instrumentTreeNode, -1 /*Force update*/ );
444             }
445         }
446     }
447
448     /**
449      * Refreshes the entire Tree Model with the latest information from the server.
450      * This should be called whenever a refresh is needed, or whenever the status
451      * of the connection to the server changes.
452      */

453     void refreshModel()
454     {
455         // Is the connection open or not?
456
if ( m_connection.isConnected() != m_lastConnected )
457         {
458             m_root.removeAllChildren();
459             m_elementMap.clear();
460             m_leasedSampleMap.clear();
461             m_leasedSampleArray = null;
462             m_lastClientStateVersion = -1;
463             fireTreeStructureChanged( new TreeModelEvent JavaDoc( this, m_root.getPath() ) );
464         }
465         
466         if ( m_connection.isConnected() )
467         {
468             // Need to update the child nodes. (Root Instrumentables)
469
updateInstrumentManagerData(
470                 m_connection.getInstrumentManager(), m_root, m_lastClientStateVersion );
471         }
472         
473         m_lastConnected = m_connection.isConnected();
474     }
475
476     /**
477      * Called to update the local view of the InstrumentManagerData in the TreeeModel.
478      *
479      * @param manager The InstrumentManagerData to use for the update.
480      * @param roorTreeNode The TreeNode representing the client.
481      * @param oldStateVersion The state version at the time of the last update.
482      */

483     private void updateInstrumentManagerData( InstrumentManagerData manager,
484                                               DefaultMutableTreeNode JavaDoc rootTreeNode,
485                                               int oldStateVersion )
486     {
487         int stateVersion = manager.getStateVersion();
488         if ( stateVersion == oldStateVersion )
489         {
490             // Already up to date.
491
return;
492         }
493
494         if ( getLogger().isDebugEnabled() )
495         {
496             getLogger().debug( "update manager(" + manager.getName() + ") "
497                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
498         }
499
500         // The latest Instrumentables will be in the correct order.
501
InstrumentableData[] instrumentables = manager.getInstrumentables();
502         int i;
503         for ( i = 0; i < instrumentables.length; i++ )
504         {
505             InstrumentableData instrumentable = instrumentables[i];
506             int oldInstrumentableStateVersion = -1;
507             DefaultMutableTreeNode JavaDoc newChild = null;
508             int childCount = rootTreeNode.getChildCount();
509             if ( i < childCount )
510             {
511                 int cmp;
512                 do {
513                     DefaultMutableTreeNode JavaDoc oldChild =
514                         (DefaultMutableTreeNode JavaDoc)rootTreeNode.getChildAt( i );
515                     cmp = ((InstrumentableNodeData)oldChild.getUserObject()).getDescription().
516                         compareTo( instrumentable.getDescription() );
517                     if ( cmp == 0 )
518                     {
519                         // This is the same object.
520
InstrumentableNodeData nodeData =
521                             (InstrumentableNodeData)oldChild.getUserObject();
522                         oldInstrumentableStateVersion = nodeData.getStateVersion();
523                         if ( nodeData.update() )
524                         {
525                             // The contents of the node changed.
526
fireTreeNodesChanged( new TreeModelEvent JavaDoc( this,
527                                 rootTreeNode.getPath(), new int[] { i }, new Object JavaDoc[] { oldChild } ) );
528                         }
529                         newChild = oldChild;
530
531                         // Node already in the elementMap
532
}
533                     else if ( cmp > 0 )
534                     {
535                         // Need to insert a new node.
536
newChild = new DefaultMutableTreeNode JavaDoc(
537                             new InstrumentableNodeData( instrumentable ), true );
538                         rootTreeNode.insert( newChild, i );
539                         fireTreeNodesInserted( new TreeModelEvent JavaDoc( this,
540                             rootTreeNode.getPath(),new int[] { i }, new Object JavaDoc[] { newChild } ) );
541
542                         // Add the new node to the elementMap
543
m_elementMap.put( ((InstrumentableNodeData)newChild.getUserObject()).
544                             getName(), newChild );
545                     }
546                     else if ( cmp < 0 )
547                     {
548                         // Need to remove an old node.
549
rootTreeNode.remove( i );
550                         fireTreeNodesRemoved( new TreeModelEvent JavaDoc( this,
551                             rootTreeNode.getPath(), new int[] { i }, new Object JavaDoc[] { oldChild } ) );
552
553                         // Remove the old node from the elementMap
554
m_elementMap.remove( ((InstrumentableNodeData)oldChild.getUserObject()).
555                             getName() );
556                     }
557                 } while ( cmp < 0 );
558             }
559             else
560             {
561                 // Append the new descriptor
562
newChild = new DefaultMutableTreeNode JavaDoc(
563                     new InstrumentableNodeData( instrumentable ), true );
564                 rootTreeNode.insert( newChild, i );
565                 fireTreeNodesInserted( new TreeModelEvent JavaDoc( this, rootTreeNode.getPath(),
566                     new int[] { i }, new Object JavaDoc[] { newChild } ) );
567
568                 // Add the new node to the elementMap
569
m_elementMap.put( ((InstrumentableNodeData)newChild.getUserObject()).
570                     getName(), newChild );
571             }
572
573             updateInstrumentable( instrumentable, newChild, oldInstrumentableStateVersion );
574         }
575         // Remove any remaining old nodes
576
while ( i < rootTreeNode.getChildCount() )
577         {
578             // Need to remove an old node.
579
DefaultMutableTreeNode JavaDoc oldChild = (DefaultMutableTreeNode JavaDoc)rootTreeNode.getChildAt( i );
580             rootTreeNode.remove( i );
581             fireTreeNodesRemoved( new TreeModelEvent JavaDoc(
582                 this, rootTreeNode.getPath(), new int[] { i }, new Object JavaDoc[] { oldChild } ) );
583
584             // Remove the old node from the elementMap
585
m_elementMap.remove( ((InstrumentableNodeData)oldChild.getUserObject()).
586                 getName() );
587         }
588
589         m_lastClientStateVersion = stateVersion;
590     }
591
592     /**
593      * @param instrumentableData The Instrumentable to update.
594      * @param instrumentableTreeNode The tree node of the Instrumentable to
595      * update.
596      * @param oldStateVersion The state version at the time of the last update.
597      */

598     private void updateInstrumentable( InstrumentableData instrumentableData,
599                                        DefaultMutableTreeNode JavaDoc instrumentableTreeNode,
600                                        int oldStateVersion )
601     {
602         int stateVersion = instrumentableData.getStateVersion();
603         if ( stateVersion == oldStateVersion )
604         {
605             // Already up to date.
606
return;
607         }
608
609         if ( getLogger().isDebugEnabled() )
610         {
611             getLogger().debug( "update instrumentable(" + instrumentableData.getName() + ") "
612                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
613         }
614
615         // The latest Instrumentables will be in the correct order.
616
InstrumentableData[] childInstrumentables = instrumentableData.getInstrumentables();
617         //System.out.println("Model.updateInstumentable() " + instrumentableData.getName() + " " + childInstrumentables.length);
618
int i;
619         for ( i = 0; i < childInstrumentables.length; i++ )
620         {
621             InstrumentableData childInstrumentable = childInstrumentables[i];
622             int oldInstrumentableStateVersion = -1;
623             //System.out.println(" " + childInstrumentable.getName() );
624
DefaultMutableTreeNode JavaDoc newChild = null;
625             int childCount = instrumentableTreeNode.getChildCount();
626             if ( i < childCount )
627             {
628                 int cmp;
629                 do {
630                     DefaultMutableTreeNode JavaDoc oldChild =
631                         (DefaultMutableTreeNode JavaDoc)instrumentableTreeNode.getChildAt( i );
632                     if ( oldChild.getUserObject() instanceof InstrumentableNodeData )
633                     {
634                         cmp = ((InstrumentableNodeData)oldChild.getUserObject()).getDescription().
635                             compareTo( childInstrumentable.getDescription() );
636                     }
637                     else
638                     {
639                         // Always put Instrumentables before any other nodes.
640
cmp = 1;
641                     }
642
643                     if ( cmp == 0 )
644                     {
645                         // This is the same object.
646
InstrumentableNodeData nodeData =
647                             (InstrumentableNodeData)oldChild.getUserObject();
648                         oldInstrumentableStateVersion = nodeData.getStateVersion();
649                         if ( nodeData.update() )
650                         {
651                             // The contents of the node changed.
652
fireTreeNodesChanged( new TreeModelEvent JavaDoc( this,
653                                 instrumentableTreeNode.getPath(), new int[] { i },
654                                 new Object JavaDoc[] { oldChild } ) );
655                         }
656                         newChild = oldChild;
657
658                         // Node already in the elementMap
659
}
660                     else if ( cmp > 0 )
661                     {
662                         // Need to insert a new node.
663
newChild = new DefaultMutableTreeNode JavaDoc(
664                             new InstrumentableNodeData( childInstrumentable ), true );
665                         instrumentableTreeNode.insert( newChild, i );
666                         fireTreeNodesInserted( new TreeModelEvent JavaDoc( this,
667                             instrumentableTreeNode.getPath(),new int[] { i },
668                             new Object JavaDoc[] { newChild } ) );
669
670                         // Add the new node to the elementMap
671
m_elementMap.put( ((InstrumentableNodeData)newChild.getUserObject()).
672                             getName(), newChild );
673                     }
674                     else if ( cmp < 0 )
675                     {
676                         // Need to remove an old node.
677
instrumentableTreeNode.remove( i );
678                         fireTreeNodesRemoved( new TreeModelEvent JavaDoc( this,
679                             instrumentableTreeNode.getPath(), new int[] { i },
680                             new Object JavaDoc[] { oldChild } ) );
681
682                         // Remove the old node from the elementMap
683
m_elementMap.remove( ((InstrumentableNodeData)oldChild.getUserObject()).
684                             getName() );
685                     }
686                 } while ( cmp < 0 );
687             }
688             else
689             {
690                 // Append the new descriptor
691
newChild = new DefaultMutableTreeNode JavaDoc(
692                     new InstrumentableNodeData( childInstrumentable ), true );
693                 instrumentableTreeNode.insert( newChild, i );
694                 fireTreeNodesInserted( new TreeModelEvent JavaDoc( this, instrumentableTreeNode.getPath(),
695                     new int[] { i }, new Object JavaDoc[] { newChild } ) );
696
697                 // Add the new node to the elementMap
698
m_elementMap.put( ((InstrumentableNodeData)newChild.getUserObject()).
699                     getName(), newChild );
700             }
701
702             updateInstrumentable( childInstrumentable, newChild, oldInstrumentableStateVersion );
703         }
704         // Remove any remaining old Instrumentable nodes
705
while ( i < instrumentableTreeNode.getChildCount() )
706         {
707             // Need to remove an old node.
708
DefaultMutableTreeNode JavaDoc oldChild =
709                 (DefaultMutableTreeNode JavaDoc)instrumentableTreeNode.getChildAt( i );
710             if ( !( oldChild.getUserObject() instanceof InstrumentableNodeData ) )
711             {
712                 break;
713             }
714
715             instrumentableTreeNode.remove( i );
716             fireTreeNodesRemoved( new TreeModelEvent JavaDoc(
717                 this, instrumentableTreeNode.getPath(), new int[] { i },
718                 new Object JavaDoc[] { oldChild } ) );
719
720             // Remove the old node from the elementMap
721
m_elementMap.remove( ((InstrumentableNodeData)oldChild.getUserObject()).
722                 getName() );
723         }
724
725
726         // The latest Instruments will be in the correct order.
727
InstrumentData[] instruments =
728             instrumentableData.getInstruments();
729         for ( i = childInstrumentables.length; i < instruments.length + childInstrumentables.length; i++ )
730         {
731             InstrumentData instrument = instruments[i - childInstrumentables.length];
732             int oldInstrumentStateVersion = -1;
733             //System.out.println(" " + instrument.getName() );
734
DefaultMutableTreeNode JavaDoc newChild = null;
735             int childCount = instrumentableTreeNode.getChildCount();
736             if ( i < childCount )
737             {
738                 int cmp;
739                 do {
740                     DefaultMutableTreeNode JavaDoc oldChild =
741                         (DefaultMutableTreeNode JavaDoc)instrumentableTreeNode.getChildAt( i );
742                     if ( oldChild.getUserObject() instanceof InstrumentNodeData )
743                     {
744                         cmp = ((InstrumentNodeData)oldChild.getUserObject()).getDescription().
745                             compareTo( instrument.getDescription() );
746                     }
747                     else
748                     {
749                         // Always put Instrumentables before any other nodes.
750
cmp = 1;
751                     }
752
753                     if ( cmp == 0 )
754                     {
755                         // This is the same object.
756
InstrumentNodeData nodeData = (InstrumentNodeData)oldChild.getUserObject();
757                         oldInstrumentStateVersion = nodeData.getStateVersion();
758                         if ( nodeData.update() )
759                         {
760                             // The contents of the node changed.
761
fireTreeNodesChanged( new TreeModelEvent JavaDoc( this,
762                                 instrumentableTreeNode.getPath(), new int[] { i },
763                                 new Object JavaDoc[] { oldChild } ) );
764                         }
765                         newChild = oldChild;
766
767                         // Node already in the elementMap
768
}
769                     else if ( cmp > 0 )
770                     {
771                         // Need to insert a new node.
772
newChild = new DefaultMutableTreeNode JavaDoc(
773                             new InstrumentNodeData( instrument, m_connection ), true );
774                         instrumentableTreeNode.insert( newChild, i );
775                         fireTreeNodesInserted( new TreeModelEvent JavaDoc( this,
776                             instrumentableTreeNode.getPath(),new int[] { i },
777                             new Object JavaDoc[] { newChild } ) );
778
779                         // Add the new node to the elementMap
780
m_elementMap.put( ((InstrumentNodeData)newChild.getUserObject()).
781                             getName(), newChild );
782                     }
783                     else if ( cmp < 0 )
784                     {
785                         // Need to remove an old node.
786
instrumentableTreeNode.remove( i );
787                         fireTreeNodesRemoved( new TreeModelEvent JavaDoc( this,
788                             instrumentableTreeNode.getPath(), new int[] { i },
789                             new Object JavaDoc[] { oldChild } ) );
790
791                         // Remove the old node from the elementMap
792
m_elementMap.remove( ((InstrumentNodeData)oldChild.getUserObject()).
793                             getName() );
794                     }
795                 } while ( cmp < 0 );
796             }
797             else
798             {
799                 // Append the new descriptor
800
newChild = new DefaultMutableTreeNode JavaDoc(
801                     new InstrumentNodeData( instrument, m_connection ), true );
802                 instrumentableTreeNode.insert( newChild, i );
803                 fireTreeNodesInserted( new TreeModelEvent JavaDoc( this, instrumentableTreeNode.getPath(),
804                     new int[] { i }, new Object JavaDoc[] { newChild } ) );
805
806                 // Add the new node to the elementMap
807
m_elementMap.put( ((InstrumentNodeData)newChild.getUserObject()).
808                     getName(), newChild );
809             }
810
811             updateInstrument( instrument, newChild, oldInstrumentStateVersion );
812         }
813         // Remove any remaining old Instrument nodes
814
while ( i < instrumentableTreeNode.getChildCount() )
815         {
816             // Need to remove an old node.
817
DefaultMutableTreeNode JavaDoc oldChild =
818                 (DefaultMutableTreeNode JavaDoc)instrumentableTreeNode.getChildAt( i );
819             instrumentableTreeNode.remove( i );
820             fireTreeNodesRemoved( new TreeModelEvent JavaDoc(
821                 this, instrumentableTreeNode.getPath(), new int[] { i },
822                 new Object JavaDoc[] { oldChild } ) );
823
824             // Remove the old node from the elementMap
825
m_elementMap.remove( ((InstrumentNodeData)oldChild.getUserObject()).
826                 getName() );
827         }
828     }
829
830     /**
831      * @param instrumentData The Instrument to update.
832      */

833     void updateInstrument( InstrumentData instrumentData )
834     {
835         // Find the tree node.
836
DefaultMutableTreeNode JavaDoc instrumentTreeNode =
837             getInstrumentTreeNode( instrumentData.getName() );
838         if ( instrumentTreeNode != null )
839         {
840             updateInstrument( instrumentData, instrumentTreeNode, -1 /* Force update */ );
841         }
842     }
843
844     /**
845      * @param instrumentData The Instrument to update.
846      * @param instrumentTreeNode The tree node of the Instrument to update.
847      */

848     void updateInstrument( InstrumentData instrumentData,
849                            DefaultMutableTreeNode JavaDoc instrumentTreeNode,
850                            int oldStateVersion )
851     {
852         int stateVersion = instrumentData.getStateVersion();
853         if ( stateVersion == oldStateVersion )
854         {
855             // Already up to date.
856
return;
857         }
858
859         if ( getLogger().isDebugEnabled() )
860         {
861             getLogger().debug( "update instrument(" + instrumentData.getName() + ") "
862                 + "state new=" + stateVersion + ", old=" + oldStateVersion );
863         }
864
865         // The latest Instrument Samples will be in the correct order.
866
InstrumentSampleData[] samples =
867             instrumentData.getInstrumentSamples();
868         //System.out.println("Model.updateInstument() " + instrumentDescriptor.getName() + " " + descriptors.length);
869
int i;
870         for ( i = 0; i < samples.length; i++ )
871         {
872             InstrumentSampleData sample = samples[i];
873             //System.out.println(" " + sample.getName() );
874
DefaultMutableTreeNode JavaDoc newChild = null;
875             int childCount = instrumentTreeNode.getChildCount();
876             if ( i < childCount )
877             {
878                 int cmp;
879                 do {
880                     // Old child will always be a sample
881
DefaultMutableTreeNode JavaDoc oldChild =
882                         (DefaultMutableTreeNode JavaDoc)instrumentTreeNode.getChildAt( i );
883                     cmp = ((InstrumentSampleNodeData)oldChild.getUserObject()).
884                         getDescription().compareTo( sample.getDescription() );
885
886                     if ( cmp == 0 )
887                     {
888                         // This is the same object.
889
if ( ((InstrumentSampleNodeData)oldChild.getUserObject()).update() )
890                         {
891                             // The contents of the node changed.
892
fireTreeNodesChanged( new TreeModelEvent JavaDoc( this,
893                                 instrumentTreeNode.getPath(), new int[] { i },
894                                 new Object JavaDoc[] { oldChild } ) );
895                         }
896                         newChild = oldChild;
897
898                         // Node already in the elementMap
899
}
900                     else if ( cmp > 0 )
901                     {
902                         // Need to insert a new node.
903
newChild = new DefaultMutableTreeNode JavaDoc(
904                             new InstrumentSampleNodeData( instrumentData.getName(),
905                             sample, m_connection ), true );
906                         instrumentTreeNode.insert( newChild, i );
907                         fireTreeNodesInserted( new TreeModelEvent JavaDoc( this,
908                             instrumentTreeNode.getPath(),new int[] { i },
909                             new Object JavaDoc[] { newChild } ) );
910
911                         // Add the new node to the elementMap
912
InstrumentSampleNodeData newNodeData =
913                             (InstrumentSampleNodeData)newChild.getUserObject();
914                         String JavaDoc sampleName = newNodeData.getName();
915                         m_elementMap.put( sampleName, newChild );
916                         if ( newNodeData.isLeased() )
917                         {
918                             m_leasedSampleMap.put( sampleName, newChild );
919                             m_leasedSampleArray = null;
920                         }
921
922                         // Make sure that the maintained flag is set correctly
923
MaintainedSampleLease lease =
924                             m_connection.getMaintainedSampleLease( sampleName );
925                         if ( lease != null )
926                         {
927                             newNodeData.setLeaseDuration( lease.getLeaseDuration() );
928                         }
929                     }
930                     else if ( cmp < 0 )
931                     {
932                         // Need to remove an old node.
933
instrumentTreeNode.remove( i );
934                         fireTreeNodesRemoved( new TreeModelEvent JavaDoc( this,
935                             instrumentTreeNode.getPath(), new int[] { i },
936                             new Object JavaDoc[] { oldChild } ) );
937
938                         // Remove the old node from the elementMap
939
InstrumentSampleNodeData oldNodeData =
940                             (InstrumentSampleNodeData)oldChild.getUserObject();
941                         String JavaDoc sampleName = oldNodeData.getName();
942                         m_elementMap.remove( sampleName );
943                         if ( oldNodeData.isLeased() )
944                         {
945                             m_leasedSampleMap.remove( sampleName );
946                             m_leasedSampleArray = null;
947                         }
948                     }
949                 } while ( cmp < 0 );
950             }
951             else
952             {
953                 // Append the new descriptor
954
newChild = new DefaultMutableTreeNode JavaDoc(
955                     new InstrumentSampleNodeData( instrumentData.getName(), sample, m_connection ),
956                     true );
957                 instrumentTreeNode.insert( newChild, i );
958                 fireTreeNodesInserted( new TreeModelEvent JavaDoc( this, instrumentTreeNode.getPath(),
959                     new int[] { i }, new Object JavaDoc[] { newChild } ) );
960
961                 // Add the new node to the elementMap
962
InstrumentSampleNodeData newNodeData =
963                     (InstrumentSampleNodeData)newChild.getUserObject();
964                 String JavaDoc sampleName = newNodeData.getName();
965                 m_elementMap.put( sampleName, newChild );
966                 if ( newNodeData.isLeased() )
967                 {
968                     m_leasedSampleMap.put( sampleName, newChild );
969                     m_leasedSampleArray = null;
970                 }
971
972                 // Make sure that the maintained flag is set correctly
973
MaintainedSampleLease lease =
974                     m_connection.getMaintainedSampleLease( sampleName );
975                 if ( lease != null )
976                 {
977                     newNodeData.setLeaseDuration( lease.getLeaseDuration() );
978                 }
979             }
980         }
981         // Remove any remaining old Instrument Sample nodes
982
while ( i < instrumentTreeNode.getChildCount() )
983         {
984             // Need to remove an old node.
985
DefaultMutableTreeNode JavaDoc oldChild =
986                 (DefaultMutableTreeNode JavaDoc)instrumentTreeNode.getChildAt( i );
987
988             instrumentTreeNode.remove( i );
989             fireTreeNodesRemoved( new TreeModelEvent JavaDoc(
990                 this, instrumentTreeNode.getPath(), new int[] { i },
991                 new Object JavaDoc[] { oldChild } ) );
992
993             // Remove the old node from the elementMap
994
InstrumentSampleNodeData oldNodeData =
995                 (InstrumentSampleNodeData)oldChild.getUserObject();
996             String JavaDoc sampleName = oldNodeData.getName();
997             m_elementMap.remove( sampleName );
998             if ( oldNodeData.isLeased() )
999             {
1000                m_leasedSampleMap.remove( sampleName );
1001                m_leasedSampleArray = null;
1002            }
1003        }
1004    }
1005
1006    /**
1007     * @param sampleData The Instrument Sample to update.
1008     */

1009    void updateInstrumentSample( InstrumentSampleData sampleData )
1010    {
1011        // Find the tree node.
1012
DefaultMutableTreeNode JavaDoc sampleTreeNode =
1013            getInstrumentSampleTreeNode( sampleData.getName() );
1014        if ( sampleTreeNode != null )
1015        {
1016            updateInstrumentSample( sampleData, sampleTreeNode );
1017        }
1018    }
1019
1020    /**
1021     * @param sampleData The Instrument Sample to update.
1022     * @param sampleTreeNode The tree node of the Instrument Sample to update.
1023     */

1024    void updateInstrumentSample( InstrumentSampleData sampleData,
1025                                 DefaultMutableTreeNode JavaDoc sampleTreeNode )
1026    {
1027        // An update here should always lead to an event being fired.
1028
((InstrumentSampleNodeData)sampleTreeNode.getUserObject()).update();
1029
1030        // The contents of the node changed.
1031
fireTreeNodesChanged( new TreeModelEvent JavaDoc( this,
1032            sampleTreeNode.getPath(), new int[ 0 ], new Object JavaDoc[ 0 ] ) );
1033    }
1034}
1035
Popular Tags