1 19 20 package org.apache.excalibur.instrument.client; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Color ; 24 import java.awt.FlowLayout ; 25 import java.awt.event.ActionEvent ; 26 import java.beans.PropertyVetoException ; 27 import java.util.ArrayList ; 28 import java.util.HashMap ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import javax.swing.AbstractAction ; 33 import javax.swing.Action ; 34 import javax.swing.Box ; 35 import javax.swing.JButton ; 36 import javax.swing.JComponent ; 37 import javax.swing.JLabel ; 38 import javax.swing.JPanel ; 39 import javax.swing.SwingUtilities ; 40 import javax.swing.tree.DefaultMutableTreeNode ; 41 42 import org.apache.avalon.framework.configuration.Configuration; 43 import org.apache.avalon.framework.configuration.ConfigurationException; 44 import org.apache.avalon.framework.configuration.DefaultConfiguration; 45 import org.apache.avalon.framework.logger.LogEnabled; 46 import org.apache.avalon.framework.logger.Logger; 47 48 55 public abstract class InstrumentManagerConnection 56 extends JComponent 57 implements LogEnabled, Runnable 58 { 59 private Logger m_logger; 60 private InstrumentManagerTreeModel m_treeModel; 61 private InstrumentManagerTree m_tree; 62 63 private InstrumentClientFrame m_frame; 64 65 private boolean m_deleted; 66 private Thread m_runner; 67 68 private JLabel m_descriptionLabel; 69 70 private final List m_listeners = new ArrayList (); 71 private InstrumentManagerConnectionListener[] m_listenerArray = null; 72 73 private long m_lastLeaseRenewalTime; 74 private HashMap m_maintainedSampleLeaseMap = new HashMap (); 75 private MaintainedSampleLease[] m_maintainedSampleLeaseArray = null; 76 77 78 private Map m_sampleFrames = new HashMap (); 79 private InstrumentSampleFrame[] m_sampleFrameArray = null; 80 81 84 87 public InstrumentManagerConnection() 88 { 89 } 90 91 92 95 public void enableLogging( Logger logger ) 96 { 97 m_logger = logger.getChildLogger( "conn_" + getKey() ); 98 } 99 100 protected Logger getLogger() 101 { 102 return m_logger; 103 } 104 105 108 public void run() 109 { 110 getLogger().debug( "Started " + Thread.currentThread().getName() ); 111 try 112 { 113 while( m_runner != null ) 114 { 115 try 116 { 117 try 118 { 119 Thread.sleep( 1000 ); 120 } 121 catch( InterruptedException e ) 122 { 123 if ( m_runner == null ) 124 { 125 return; 126 } 127 } 128 129 update(); 130 131 m_frame.updateConnectionTab( this ); 132 133 updateSampleFrames(); 134 } 135 catch( Throwable t ) 136 { 137 getLogger().error( 139 "Unexpected error caught in " + Thread.currentThread().getName(), t ); 140 141 try 143 { 144 Thread.sleep( 5000 ); 145 } 146 catch ( InterruptedException e ) 147 { 148 if ( m_runner == null ) 149 { 150 return; 151 } 152 } 153 } 154 } 155 } 156 finally 157 { 158 getLogger().debug( "Stopped " + Thread.currentThread().getName() ); 159 } 160 } 161 162 165 170 final void setFrame( InstrumentClientFrame frame ) 171 { 172 m_frame = frame; 173 } 174 175 180 final InstrumentClientFrame getFrame() 181 { 182 return m_frame; 183 } 184 185 188 public void init() 189 { 190 m_treeModel = new InstrumentManagerTreeModel( this ); 191 m_treeModel.enableLogging( m_logger.getChildLogger( "treeModel" ) ); 192 addInstrumentManagerConnectionListener( m_treeModel ); 193 194 setLayout( new BorderLayout () ); 195 196 Box topPane = Box.createVerticalBox(); 198 199 Box labels = Box.createHorizontalBox(); 202 labels.add( Box.createHorizontalStrut( 4 ) ); 203 m_descriptionLabel = new JLabel ( getInstrumentManager().getDescription() ); 204 labels.add( m_descriptionLabel ); 205 labels.add( Box.createHorizontalGlue() ); 206 topPane.add( labels ); 207 208 labels = Box.createHorizontalBox(); 210 labels.add( Box.createHorizontalStrut( 4 ) ); 211 labels.add( new JLabel ( "URL: " + getKey().toString() ) ); 212 labels.add( Box.createHorizontalGlue() ); 213 topPane.add( labels ); 214 215 topPane.add( Box.createVerticalStrut( 4 ) ); 216 217 Action gcAction = new AbstractAction ( "Invoke GC" ) 219 { 220 public void actionPerformed( ActionEvent event ) 221 { 222 SwingUtilities.invokeLater( new Runnable () 223 { 224 public void run() 225 { 226 InstrumentManagerConnection.this.invokeGC(); 227 } 228 }); 229 } 230 }; 231 JButton gcButton = new JButton ( gcAction ); 232 233 Action refreshAction = new AbstractAction ( "Refresh" ) 234 { 235 public void actionPerformed( ActionEvent event ) 236 { 237 SwingUtilities.invokeLater( new Runnable () 238 { 239 public void run() 240 { 241 InstrumentManagerConnection.this.getTreeModel().refreshModel(); 242 } 243 }); 244 } 245 }; 246 JButton refreshButton = new JButton ( refreshAction ); 247 248 Action deleteAction = new AbstractAction ( "Delete" ) 249 { 250 public void actionPerformed( ActionEvent event ) 251 { 252 SwingUtilities.invokeLater( new Runnable () 253 { 254 public void run() 255 { 256 InstrumentManagerConnection.this.delete(); 257 } 258 }); 259 } 260 }; 261 JButton deleteButton = new JButton ( deleteAction ); 262 263 Box buttons = Box.createHorizontalBox(); 264 buttons.add( Box.createHorizontalStrut( 4 ) ); 265 buttons.add ( gcButton ); 266 buttons.add( Box.createHorizontalStrut( 4 ) ); 267 buttons.add ( refreshButton ); 268 buttons.add( Box.createHorizontalStrut( 4 ) ); 269 buttons.add ( deleteButton ); 270 buttons.add( Box.createHorizontalGlue() ); 271 topPane.add( buttons ); 272 273 topPane.add( Box.createVerticalStrut( 4 ) ); 274 275 add( topPane, BorderLayout.NORTH ); 276 277 m_tree = new InstrumentManagerTree( this ); 279 add( m_tree, BorderLayout.CENTER ); 280 281 m_runner = new Thread ( this, "InstrumentManagerConnection[" + getKey() + "]" ); 282 m_runner.start(); 283 } 284 285 290 public boolean isDeleted() 291 { 292 return m_deleted; 293 } 294 295 300 public String getTabTitle() 301 { 302 return getInstrumentManager().getName(); 303 } 304 305 310 public String getTabTooltip() 311 { 312 String key = getKey().toString(); 313 String tab = getInstrumentManager().getDescription(); 314 315 if ( key.equals( tab ) ) 316 { 317 return tab; 318 } 319 else 320 { 321 return tab + " [" + key + "]"; 322 } 323 } 324 325 330 public String getTitle() 331 { 332 return getInstrumentManager().getDescription(); 333 } 334 335 340 public abstract Object getKey(); 341 342 347 public abstract boolean isConnected(); 348 349 354 public abstract InstrumentManagerData getInstrumentManager(); 355 356 360 public void update() 361 { 362 if ( isConnected() ) 365 { 366 getInstrumentManager().update(); 367 } 368 else 369 { 370 getInstrumentManager().updateAll(); 371 } 372 373 String description = getInstrumentManager().getDescription(); 374 if ( !m_descriptionLabel.getText().equals( description ) ) 375 { 376 m_descriptionLabel.setText( description ); 377 } 378 379 getTreeModel().refreshModel(); 380 381 if ( isConnected() ) 383 { 384 handleLeasedSamples(); 385 } 386 } 387 388 391 protected abstract void invokeGC(); 392 393 398 public Configuration saveState() 399 { 400 synchronized( this ) 401 { 402 DefaultConfiguration state = new DefaultConfiguration( "connection", "-" ); 403 404 MaintainedSampleLease[] samples = getMaintainedSampleLeaseArray(); 406 for ( int i = 0; i < samples.length; i++ ) 407 { 408 state.addChild( samples[ i ].saveState() ); 409 } 410 411 return state; 412 } 413 } 414 415 423 public void loadState( Configuration state ) 424 throws ConfigurationException 425 { 426 synchronized( this ) 427 { 428 Configuration[] sampleConfs = state.getChildren( "maintained-sample" ); 430 for( int i = 0; i < sampleConfs.length; i++ ) 431 { 432 Configuration sampleConf = sampleConfs[ i ]; 433 String instrumentName = sampleConf.getAttribute( "instrument-name" ); 434 int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType( 435 sampleConf.getAttribute( "type" ) ); 436 long sampleInterval = sampleConf.getAttributeAsLong( "interval" ); 437 int sampleSize = sampleConf.getAttributeAsInteger( "size" ); 438 long sampleLeaseDuration = sampleConf.getAttributeAsLong( "lease-duration" ); 439 String sampleDescription = sampleConf.getAttribute( "description" ); 440 441 startMaintainingSample( instrumentName, sampleType, sampleInterval, sampleSize, 442 sampleLeaseDuration, sampleDescription ); 443 } 444 } 445 } 446 447 453 public void updateSampleFrames() 454 { 455 InstrumentSampleFrame[] frames = getSampleFrameArray(); 456 for ( int i = 0; i < frames.length; i++ ) 457 { 458 InstrumentSampleFrame frame = frames[i]; 459 frame.update(); 460 } 461 } 462 463 469 InstrumentManagerTreeModel getTreeModel() 470 { 471 return m_treeModel; 472 } 473 474 DefaultMutableTreeNode getInstrumentSampleTreeNode( String sampleName ) 475 { 476 return m_treeModel.getInstrumentSampleTreeNode( sampleName ); 477 } 478 479 486 void addInstrumentManagerConnectionListener( 487 InstrumentManagerConnectionListener listener ) 488 { 489 synchronized (this) 490 { 491 m_listeners.add( listener ); 492 m_listenerArray = null; 493 } 494 } 495 496 503 void removeInstrumentManagerConnectionListener( 504 InstrumentManagerConnectionListener listener ) 505 { 506 synchronized (this) 507 { 508 m_listeners.remove( listener ); 509 m_listenerArray = null; 510 } 511 } 512 513 519 protected InstrumentManagerConnectionListener[] getListenerArray() 520 { 521 InstrumentManagerConnectionListener[] listenerArray = m_listenerArray; 522 if ( listenerArray == null ) 523 { 524 synchronized(this) 525 { 526 m_listenerArray = new InstrumentManagerConnectionListener[ m_listeners.size() ]; 527 m_listeners.toArray( m_listenerArray ); 528 listenerArray = m_listenerArray; 529 } 530 } 531 return listenerArray; 532 } 533 534 540 InstrumentSampleSnapshotData getSampleSnapshot( String sampleName ) 541 { 542 DefaultMutableTreeNode sampleNode = getInstrumentSampleTreeNode( sampleName ); 543 if ( sampleNode == null ) 544 { 545 return null; 546 } 547 548 InstrumentSampleNodeData sampleNodeData = 549 (InstrumentSampleNodeData)sampleNode.getUserObject(); 550 InstrumentSampleData sampleData = sampleNodeData.getData(); 551 if ( sampleData == null ) 552 { 553 return null; 554 } 555 556 return sampleData.getSnapshot(); 558 } 559 560 568 private InstrumentSampleFrame getSampleFrame( String sampleName ) 569 { 570 getLogger().debug("InstrumentManagerConnection.getSampleFrame(" + sampleName + ")"); 571 return (InstrumentSampleFrame)m_sampleFrames.get( sampleName ); 573 } 574 575 579 private void addSampleFrame( String sampleName, InstrumentSampleFrame sampleFrame ) 580 { 581 getLogger().debug("InstrumentManagerConnection.addSampleFrame(" + sampleName + ", frame)"); 582 m_sampleFrames.put( sampleName, sampleFrame ); 584 m_sampleFrameArray = null; 585 } 586 587 591 private void removeSampleFrame( String sampleName ) 592 { 593 getLogger().debug("InstrumentManagerConnection.removeSampleFrame(" + sampleName + ")"); 594 m_sampleFrames.remove( sampleName ); 596 m_sampleFrameArray = null; 597 } 598 599 604 protected InstrumentSampleFrame[] getSampleFrameArray() 605 { 606 InstrumentSampleFrame[] array = m_sampleFrameArray; 607 if ( array == null ) 608 { 609 synchronized(this) 610 { 611 m_sampleFrameArray = new InstrumentSampleFrame[m_sampleFrames.size()]; 612 m_sampleFrames.values().toArray( m_sampleFrameArray ); 613 array = m_sampleFrameArray; 614 } 615 } 616 return array; 617 } 618 619 626 void loadSampleFrame( Configuration sampleFrameState ) 627 throws ConfigurationException 628 { 629 String sampleName = sampleFrameState.getAttribute( "sample" ); 631 getLogger().debug( "Loading sample frame: " + sampleName ); 632 633 InstrumentSampleFrame sampleFrame; 635 synchronized(this) 636 { 637 sampleFrame = getSampleFrame( sampleName ); 638 if ( sampleFrame != null ) 639 { 640 sampleFrame.hideFrame(); 643 sampleFrame = null; 644 } 645 646 sampleFrame = new InstrumentSampleFrame( sampleFrameState, this, m_frame ); 648 sampleFrame.enableLogging( getLogger() ); 649 addSampleFrame( sampleName, sampleFrame ); 650 sampleFrame.addToDesktop( m_frame.getDesktopPane() ); 651 } 652 sampleFrame.show(); } 654 655 660 void viewSample( String sampleName ) 661 { 662 InstrumentSampleFrame sampleFrame; 663 synchronized( this ) 664 { 665 sampleFrame = getSampleFrame( sampleName ); 667 if ( sampleFrame == null ) 668 { 669 sampleFrame = new InstrumentSampleFrame( this, sampleName, m_frame ); 670 sampleFrame.enableLogging( getLogger() ); 671 addSampleFrame( sampleName, sampleFrame ); 672 sampleFrame.addToDesktop( m_frame.getDesktopPane() ); 673 } 674 } 675 676 sampleFrame.show(); 677 if ( sampleFrame.isIcon() ) 679 { 680 try 682 { 683 sampleFrame.setIcon( false ); 684 } 685 catch ( PropertyVetoException e ) 686 { 687 getLogger().warn( "Unexpected error", e ); 689 } 690 } 691 692 try 694 { 695 sampleFrame.setSelected( true ); 696 } 697 catch ( PropertyVetoException e ) 698 { 699 getLogger().warn( "Unexpected error", e ); 701 } 702 703 sampleFrame.update(); 705 } 706 707 708 712 void delete() 713 { 714 getLogger().debug( "delete()" ); 715 716 m_deleted = true; 717 718 Thread runner = m_runner; 719 if ( runner != null ) 720 { 721 m_runner = null; 722 runner.interrupt(); 723 } 724 725 InstrumentSampleFrame[] frames = getSampleFrameArray(); 727 for ( int i = 0; i < frames.length; i++ ) 728 { 729 frames[i].hideFrame(); 730 } 731 732 InstrumentManagerConnectionListener[] listenerArray = getListenerArray(); 734 for ( int i = 0; i < listenerArray.length; i++ ) 735 { 736 listenerArray[i].deleted( this ); 737 } 738 } 739 740 743 void hideSampleFrame( InstrumentSampleFrame sampleFrame ) 744 { 745 String sampleName = sampleFrame.getInstrumentSampleName(); 746 synchronized(this) 747 { 748 removeSampleFrame( sampleName ); 749 } 750 } 751 752 764 void startMaintainingSample( String instrumentName, 765 int type, 766 long interval, 767 int size, 768 long leaseDuration, 769 String description ) 770 { 771 if ( getLogger().isDebugEnabled() ) 772 { 773 getLogger().debug( "startMaintainingSample(" + instrumentName + ", " + type + ", " + 774 interval + ", " + size + ", " + leaseDuration + ", " + description + ")" ); 775 } 776 777 synchronized(this) 778 { 779 MaintainedSampleLease sampleLease = new MaintainedSampleLease( 780 instrumentName, type, interval, size, leaseDuration, description ); 781 String sampleName = sampleLease.getSampleName(); 782 m_maintainedSampleLeaseMap.put( sampleName, sampleLease ); 783 m_maintainedSampleLeaseArray = null; 784 785 m_lastLeaseRenewalTime = 0; 788 789 DefaultMutableTreeNode sampleTreeNode = 791 m_treeModel.getInstrumentSampleTreeNode( sampleName ); 792 793 if ( sampleTreeNode != null ) 794 { 795 InstrumentSampleNodeData sampleNodeData = 796 (InstrumentSampleNodeData)sampleTreeNode.getUserObject(); 797 798 sampleNodeData.setLeaseDuration( leaseDuration ); 799 sampleNodeData.setDescription( description ); 800 m_treeModel.updateInstrumentSample( sampleNodeData.getData(), sampleTreeNode ); 801 } 802 } 803 } 804 805 809 void stopMaintainingSample( String sampleName ) 810 { 811 if ( getLogger().isDebugEnabled() ) 812 { 813 getLogger().debug( "stopMaintainingSample(" + sampleName + ")" ); 814 } 815 816 synchronized(this) 817 { 818 m_maintainedSampleLeaseMap.remove( sampleName ); 819 m_maintainedSampleLeaseArray = null; 820 821 DefaultMutableTreeNode sampleTreeNode = 823 m_treeModel.getInstrumentSampleTreeNode( sampleName ); 824 if ( sampleTreeNode != null ) 825 { 826 InstrumentSampleNodeData sampleNodeData = 827 (InstrumentSampleNodeData)sampleTreeNode.getUserObject(); 828 829 sampleNodeData.setLeaseDuration( 0 ); 830 m_treeModel.updateInstrumentSample( sampleNodeData.getData(), sampleTreeNode ); 831 } 832 } 833 } 834 835 843 MaintainedSampleLease getMaintainedSampleLease( String sampleName ) 844 { 845 synchronized(this) 846 { 847 return (MaintainedSampleLease)m_maintainedSampleLeaseMap.get( sampleName ); 848 } 849 } 850 851 856 private MaintainedSampleLease[] getMaintainedSampleLeaseArray() 857 { 858 MaintainedSampleLease[] array = m_maintainedSampleLeaseArray; 859 if ( array == null ) 860 { 861 synchronized(this) 862 { 863 m_maintainedSampleLeaseArray = 864 new MaintainedSampleLease[ m_maintainedSampleLeaseMap.size() ]; 865 m_maintainedSampleLeaseMap.values().toArray( m_maintainedSampleLeaseArray ); 866 array = m_maintainedSampleLeaseArray; 867 } 868 } 869 return array; 870 } 871 872 876 void handleLeasedSamples() 877 { 878 880 long now = System.currentTimeMillis(); 882 if ( now - m_lastLeaseRenewalTime > 30000 ) 883 { 884 getLogger().debug( "Renew Leases:" ); 885 886 MaintainedSampleLease[] leases = getMaintainedSampleLeaseArray(); 887 String [] instrumentNames = new String [leases.length]; 888 String [] descriptions = new String [leases.length]; 889 long[] intervals = new long[leases.length]; 890 int[] sampleCounts = new int[leases.length]; 891 long[] leaseTimes = new long[leases.length]; 892 int[] sampleTypes = new int[leases.length]; 893 for ( int i = 0; i < leases.length; i++ ) 894 { 895 MaintainedSampleLease lease = leases[i]; 896 getLogger().debug( " lease: " + lease.getSampleName() ); 897 898 instrumentNames[i] = lease.getInstrumentName(); 899 descriptions[i] = lease.getDescription(); 900 intervals[i] = lease.getInterval(); 901 sampleCounts[i] = lease.getSize(); 902 leaseTimes[i] = lease.getLeaseDuration(); 903 sampleTypes[i] = lease.getType(); 904 } 905 906 getInstrumentManager().createInstrumentSamples( 910 instrumentNames, descriptions, intervals, sampleCounts, leaseTimes, sampleTypes ); 911 912 m_treeModel.renewAllSampleLeases(); 915 916 m_lastLeaseRenewalTime = now; 917 } 918 919 m_treeModel.purgeExpiredSamples(); 921 } 922 923 924 929 void showCreateSampleDialog( final InstrumentData instrumentData ) 930 { 931 SwingUtilities.invokeLater( new Runnable () 932 { 933 public void run() 934 { 935 CreateSampleDialog dialog = new CreateSampleDialog( 936 m_frame, instrumentData.getName(), instrumentData.getDescription(), 937 instrumentData.getType() ); 938 dialog.show(); 939 940 if ( dialog.getAction() == CreateSampleDialog.BUTTON_OK ) 941 { 942 String description = dialog.getSampleDescription(); 943 long interval = dialog.getInterval(); 944 int sampleCount = dialog.getSampleCount(); 945 long leaseTime = dialog.getLeaseTime(); 946 int type = dialog.getSampleType(); 947 boolean maintain = dialog.getMaintainLease(); 948 949 if ( getLogger().isDebugEnabled() ) 950 { 951 getLogger().debug( "New Sample: desc=" + description 952 + ", interval=" + interval 953 + ", size=" + sampleCount 954 + ", lease=" + leaseTime 955 + ", type=" + type 956 + ", maintain=" + maintain ); 957 } 958 959 boolean success = instrumentData.createInstrumentSample( 962 description, 963 interval, 964 sampleCount, 965 leaseTime, 966 type ); 967 968 String sampleName = InstrumentSampleUtils.generateFullInstrumentSampleName( 970 instrumentData.getName(), type, interval, sampleCount ); 971 972 if ( success ) 973 { 974 if ( maintain ) 976 { 977 startMaintainingSample( instrumentData.getName(), type, interval, 978 sampleCount, leaseTime, description ); 979 } 980 981 viewSample( sampleName ); 983 } 984 else 985 { 986 getLogger().warn( "Attempt to register the sample with the server failed: " 987 + sampleName ); 988 } 989 } 990 } 991 } ); 992 } 993 994 997 public String toString() 998 { 999 return getClass().getName() + " : " + getKey(); 1000 } 1001} | Popular Tags |