blob: 67350456d4f6180b9c319fab08bee11864f6d0c5 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2008 Oracle
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.wst.common.project.facet.ui.internal;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gd;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdfill;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhalign;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhfill;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdwhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gl;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.glmargins;
import static org.eclipse.wst.common.project.facet.ui.internal.util.SwtUtil.getPreferredWidth;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentVersion;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleEvent;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleListener;
import org.eclipse.wst.common.project.facet.core.runtime.events.IValidationStatusChangedEvent;
import org.eclipse.wst.common.project.facet.core.runtime.internal.UnknownRuntime;
import org.eclipse.wst.common.project.facet.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider;
import org.eclipse.wst.common.project.facet.ui.internal.util.BasicToolTip;
import org.osgi.framework.Bundle;
/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/
public final class RuntimesPanel
extends Composite
{
private static final Object NO_RUNTIME_SELECTED_PLACEHOLDER = new Object();
private final IFacetedProjectWorkingCopy fpjwc;
private boolean showAllRuntimesSetting;
private final CheckboxTableViewer runtimes;
private final Button showAllRuntimesCheckbox;
private final Button makePrimaryButton;
private final Button newRuntimeButton;
private final Label runtimeComponentsLabel;
private final TableViewer runtimeComponents;
private IRuntime currentPrimaryRuntime;
private final List<IFacetedProjectListener> listeners;
private Color colorGray;
private final RuntimeValidationAssistant runtimeValidationAssistant;
public RuntimesPanel( final Composite parent,
final IFacetedProjectWorkingCopy fpjwc )
{
super( parent, SWT.NONE );
this.listeners = new ArrayList<IFacetedProjectListener>();
addDisposeListener
(
new DisposeListener()
{
public void widgetDisposed( final DisposeEvent e )
{
handleWidgetDisposed();
}
}
);
// Setup runtime validation assistant.
this.runtimeValidationAssistant = new RuntimeValidationAssistant();
// Bind to the data model.
this.fpjwc = fpjwc;
addDataModelListener
(
new IFacetedProjectListener()
{
public void handleEvent( final IFacetedProjectEvent event )
{
handleAvailableRuntimesChanged();
}
},
IFacetedProjectEvent.Type.AVAILABLE_RUNTIMES_CHANGED
);
addDataModelListener
(
new IFacetedProjectListener()
{
public void handleEvent( final IFacetedProjectEvent event )
{
handleTargetableRuntimesChanged();
}
},
IFacetedProjectEvent.Type.TARGETABLE_RUNTIMES_CHANGED
);
addDataModelListener
(
new IFacetedProjectListener()
{
public void handleEvent( final IFacetedProjectEvent event )
{
handleTargetedRuntimesChanged();
}
},
IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED
);
addDataModelListener
(
new IFacetedProjectListener()
{
public void handleEvent( final IFacetedProjectEvent event )
{
handlePrimaryRuntimeChanged();
}
},
IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED
);
this.showAllRuntimesSetting = false;
// Initialize the colors.
this.colorGray = new Color( null, 160, 160, 164 );
// Layout the panel.
final GridLayout layout = new GridLayout( 1, false );
layout.marginHeight = 5;
layout.marginWidth = 5;
setLayout( layout );
this.runtimes = CheckboxTableViewer.newCheckList( this, SWT.BORDER );
this.runtimes.getTable().setLayoutData( gdfill() );
this.runtimes.setContentProvider( new ContentProvider() );
this.runtimes.setLabelProvider( new LabelProvider() );
this.runtimes.setSorter( new Sorter() );
this.runtimes.setInput( new Object() );
new ValidationProblemToolTip( this.runtimes.getTable() );
this.runtimes.addSelectionChangedListener
(
new ISelectionChangedListener()
{
public void selectionChanged( final SelectionChangedEvent e )
{
handleRuntimeSelectionChanged();
}
}
);
this.runtimes.addCheckStateListener
(
new ICheckStateListener()
{
public void checkStateChanged( final CheckStateChangedEvent e )
{
handleCheckStateChanged( e );
}
}
);
this.showAllRuntimesCheckbox = new Button( this, SWT.CHECK );
this.showAllRuntimesCheckbox.setText( Resources.showAllRuntimes );
this.showAllRuntimesCheckbox.setSelection( this.showAllRuntimesSetting );
this.showAllRuntimesCheckbox.addSelectionListener
(
new SelectionAdapter()
{
public void widgetSelected( final SelectionEvent e )
{
handleShowAllRuntimesSelected();
}
}
);
final Composite buttons = new Composite( this, SWT.NONE );
buttons.setLayoutData( gdhalign( gd(), GridData.END ) );
buttons.setLayout( glmargins( gl( 2 ), 0, 0 ) );
GridData gd;
this.makePrimaryButton = new Button( buttons, SWT.PUSH );
this.makePrimaryButton.setText( Resources.makePrimaryLabel );
gd = gdwhint( gd(), getPreferredWidth( this.makePrimaryButton ) + 15 );
this.makePrimaryButton.setLayoutData( gd );
this.makePrimaryButton.setEnabled( false );
this.makePrimaryButton.addSelectionListener
(
new SelectionAdapter()
{
public void widgetSelected( final SelectionEvent e )
{
handleMakePrimarySelected();
}
}
);
this.newRuntimeButton = new Button( buttons, SWT.PUSH );
this.newRuntimeButton.setText( Resources.newRuntimeButtonLabel );
gd = gdwhint( gd(), getPreferredWidth( this.newRuntimeButton ) + 15 );
this.newRuntimeButton.setLayoutData( gd );
this.newRuntimeButton.addSelectionListener
(
new SelectionAdapter()
{
public void widgetSelected( final SelectionEvent e )
{
handleNewRuntimeButtonSelected();
}
}
);
this.runtimeComponentsLabel = new Label( this, SWT.NONE );
this.runtimeComponentsLabel.setText( Resources.runtimeCompositionLabel );
this.runtimeComponentsLabel.setLayoutData( gdhfill() );
final Color infoBackgroundColor
= parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND );
final Color infoForegroundColor
= parent.getDisplay().getSystemColor( SWT.COLOR_INFO_FOREGROUND );
this.runtimeComponents = new TableViewer( this, SWT.BORDER );
this.runtimeComponents.getTable().setLayoutData( gdhhint( gdhfill(), 50 ) );
this.runtimeComponents.getTable().setBackground( infoBackgroundColor );
this.runtimeComponents.getTable().setForeground( infoForegroundColor );
this.runtimeComponents.setContentProvider( new RuntimeComponentsContentProvider() );
this.runtimeComponents.setLabelProvider( new RuntimeComponentsLabelProvider() );
this.runtimeComponents.setInput( NO_RUNTIME_SELECTED_PLACEHOLDER );
this.runtimeComponents.getTable().setEnabled( false );
this.runtimeComponentsLabel.setEnabled( false );
refresh();
this.currentPrimaryRuntime = this.fpjwc.getPrimaryRuntime();
Dialog.applyDialogFont( parent );
}
public IFacetedProjectWorkingCopy getFacetedProjectWorkingCopy()
{
return this.fpjwc;
}
private void handleAvailableRuntimesChanged()
{
if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
{
getDisplay().asyncExec
(
new Runnable()
{
public void run()
{
handleAvailableRuntimesChanged();
}
}
);
return;
}
if( this.showAllRuntimesSetting )
{
refresh();
}
}
private void handleTargetableRuntimesChanged()
{
if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
{
getDisplay().asyncExec
(
new Runnable()
{
public void run()
{
handleTargetableRuntimesChanged();
}
}
);
return;
}
refresh();
}
private void handleTargetedRuntimesChanged()
{
if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
{
getDisplay().asyncExec
(
new Runnable()
{
public void run()
{
handleTargetedRuntimesChanged();
}
}
);
return;
}
final Set<IRuntime> targeted = this.fpjwc.getTargetedRuntimes();
for( IRuntime r : this.fpjwc.getTargetableRuntimes() )
{
if( targeted.contains( r ) )
{
if( ! this.runtimes.getChecked( r ) )
{
this.runtimes.setChecked( r, true );
}
}
else
{
if( this.runtimes.getChecked( r ) )
{
this.runtimes.setChecked( r, false );
}
}
}
}
private void handlePrimaryRuntimeChanged()
{
if( ! Thread.currentThread().equals( getDisplay().getThread() ) )
{
getDisplay().asyncExec
(
new Runnable()
{
public void run()
{
handlePrimaryRuntimeChanged();
}
}
);
return;
}
if( this.currentPrimaryRuntime != null )
{
this.runtimes.update( this.currentPrimaryRuntime, null );
}
this.currentPrimaryRuntime = this.fpjwc.getPrimaryRuntime();
if( this.currentPrimaryRuntime != null )
{
this.runtimes.update( this.currentPrimaryRuntime, null );
}
}
private void handleCheckStateChanged( final CheckStateChangedEvent e )
{
final IRuntime runtime = (IRuntime) e.getElement();
if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( runtime ) &&
! ( runtime instanceof UnknownRuntime ) && e.getChecked() )
{
this.runtimes.setChecked( runtime, false );
return;
}
if( e.getChecked() )
{
this.fpjwc.addTargetedRuntime( runtime );
}
else
{
this.fpjwc.removeTargetedRuntime( runtime );
}
}
private void handleRuntimeSelectionChanged()
{
final IRuntime r = getSelection();
if( r == null )
{
if( this.runtimeComponents.getInput() != null )
{
this.runtimeComponentsLabel.setEnabled( false );
this.runtimeComponents.getTable().setEnabled( false );
this.runtimeComponents.setInput( NO_RUNTIME_SELECTED_PLACEHOLDER );
}
}
else
{
if( this.runtimeComponents.getInput() == null ||
! this.runtimeComponents.getInput().equals( r ) )
{
this.runtimeComponentsLabel.setEnabled( true );
this.runtimeComponents.getTable().setEnabled( true );
this.runtimeComponents.setInput( r );
}
if( this.runtimes.getChecked( r ) &&
this.fpjwc.getPrimaryRuntime() != null &&
! this.fpjwc.getPrimaryRuntime().equals( r ) &&
( this.fpjwc.getTargetableRuntimes().contains( r ) || r instanceof UnknownRuntime ) )
{
this.makePrimaryButton.setEnabled( true );
}
else
{
this.makePrimaryButton.setEnabled( false );
}
}
}
private void handleShowAllRuntimesSelected()
{
this.showAllRuntimesSetting
= this.showAllRuntimesCheckbox.getSelection();
refresh();
}
private void handleMakePrimarySelected()
{
this.fpjwc.setPrimaryRuntime( getSelection() );
}
@SuppressWarnings( "unchecked" )
private void handleNewRuntimeButtonSelected()
{
final String SERVER_UI_PLUGIN_ID = "org.eclipse.wst.server.ui"; //$NON-NLS-1$
final String CLASS_NAME = "org.eclipse.wst.server.ui.internal.ServerUIPlugin"; //$NON-NLS-1$
final String METHOD_NAME = "showNewRuntimeWizard"; //$NON-NLS-1$
final Bundle serverUiBundle = Platform.getBundle( SERVER_UI_PLUGIN_ID );
if( serverUiBundle == null )
{
this.newRuntimeButton.setEnabled( false );
return;
}
try
{
final Class serverUiPluginClass = serverUiBundle.loadClass( CLASS_NAME );
final Method method
= serverUiPluginClass.getMethod( METHOD_NAME, Shell.class, String.class );
final Object result = method.invoke( null, getShell(), null );
if( result.equals( true ) )
{
final Thread refreshThread = new Thread()
{
public void run()
{
getFacetedProjectWorkingCopy().refreshTargetableRuntimes();
}
};
refreshThread.start();
}
}
catch( Exception e )
{
FacetUiPlugin.log( e );
}
}
private void handleWidgetDisposed()
{
removeDataModelListeners();
this.colorGray.dispose();
this.runtimeValidationAssistant.dispose();
}
private void handleRuntimeValidationResultChanged()
{
final Runnable uiRunnable = new Runnable()
{
public void run()
{
for( TableItem item : RuntimesPanel.this.runtimes.getTable().getItems() )
{
RuntimesPanel.this.runtimes.update( item.getData(), null );
}
}
};
getDisplay().syncExec( uiRunnable );
}
private void refresh()
{
this.runtimes.refresh();
final Set<IRuntime> untargetable = new HashSet<IRuntime>( RuntimeManager.getRuntimes() );
untargetable.removeAll( this.fpjwc.getTargetableRuntimes() );
this.runtimes.setCheckedElements( this.fpjwc.getTargetedRuntimes().toArray() );
}
private IRuntime getSelection()
{
final IStructuredSelection ssel
= (IStructuredSelection) this.runtimes.getSelection();
if( ssel.isEmpty() )
{
return null;
}
else
{
return (IRuntime) ssel.getFirstElement();
}
}
private void addDataModelListener( final IFacetedProjectListener listener,
final IFacetedProjectEvent.Type... types )
{
this.fpjwc.addListener( listener, types );
this.listeners.add( listener );
}
private void removeDataModelListeners()
{
for( IFacetedProjectListener listener : this.listeners )
{
this.fpjwc.removeListener( listener );
}
}
private TableItem getTableItem( final int x,
final int y )
{
for( TableItem item : this.runtimes.getTable().getItems() )
{
if( item.getBounds().contains( x, y ) )
{
return item;
}
}
return null;
}
private RuntimeValidationAssistant getRuntimeValidationAssistant()
{
return this.runtimeValidationAssistant;
}
private final class ContentProvider
implements IStructuredContentProvider
{
public Object[] getElements( final Object element )
{
final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
final ArrayList<IRuntime> runtimes = new ArrayList<IRuntime>();
if( RuntimesPanel.this.showAllRuntimesSetting )
{
runtimes.addAll( RuntimeManager.getRuntimes() );
}
else
{
runtimes.addAll( fpjwc.getTargetableRuntimes() );
}
final IFacetedProject fpj = fpjwc.getFacetedProject();
if( fpj != null )
{
for( IRuntime runtime : fpj.getTargetedRuntimes() )
{
if( runtime instanceof UnknownRuntime )
{
runtimes.add( runtime );
}
}
}
return runtimes.toArray();
}
public void dispose() { }
public void inputChanged( final Viewer viewer,
final Object oldObject,
final Object newObject ) {}
}
private final class LabelProvider
implements ILabelProvider, IColorProvider
{
private final ImageRegistry imageRegistry;
public LabelProvider()
{
this.imageRegistry = new ImageRegistry();
}
public String getText( final Object element )
{
return ( (IRuntime) element ).getLocalizedName();
}
private String getImageRegistryKey( final IRuntime runtime,
final boolean isPrimary,
final IStatus validationResult )
{
final StringBuilder buf = new StringBuilder();
buf.append( runtime.getName() );
if( isPrimary )
{
buf.append( ",##primary##" ); //$NON-NLS-1$
}
if( validationResult != null && validationResult.getSeverity() == IStatus.ERROR )
{
buf.append( ",##error##" ); //$NON-NLS-1$
}
return buf.toString();
}
public Image getImage( final Object element )
{
final IRuntime r = (IRuntime) element;
final IRuntime primary = getFacetedProjectWorkingCopy().getPrimaryRuntime();
final boolean isPrimary = primary != null && primary.equals( r );
final IStatus valResult = getRuntimeValidationAssistant().getValidationResult( r );
final String imgid = getImageRegistryKey( r, isPrimary, valResult );
Image image = this.imageRegistry.get( imgid );
if( image == null )
{
final IDecorationsProvider decprov
= (IDecorationsProvider) r.getAdapter( IDecorationsProvider.class );
final ImageDescriptor imgdesc
= new DecoratedRuntimeImageDescriptor( decprov.getIcon(), isPrimary, valResult );
this.imageRegistry.put( imgid, imgdesc );
image = this.imageRegistry.get( imgid );
}
if( RuntimesPanel.this.fpjwc.getTargetedRuntimes().contains( r ) )
{
RuntimesPanel.this.runtimes.setChecked( r, true );
}
else
{
RuntimesPanel.this.runtimes.setChecked( r, false );
}
if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( r ) &&
! ( r instanceof UnknownRuntime ) )
{
final String greyedId = r.getName() + "##greyed##"; //$NON-NLS-1$
Image greyed = this.imageRegistry.get( greyedId );
if( greyed == null )
{
greyed = new Image( null, image, SWT.IMAGE_GRAY );
this.imageRegistry.put( greyedId, greyed );
}
image = greyed;
}
return image;
}
public Color getForeground( final Object element )
{
if( ! getFacetedProjectWorkingCopy().getTargetableRuntimes().contains( element ) &&
! ( element instanceof UnknownRuntime ) )
{
return RuntimesPanel.this.colorGray;
}
else
{
return null;
}
}
public Color getBackground( final Object element )
{
return null;
}
public void dispose()
{
this.imageRegistry.dispose();
}
public boolean isLabelProperty( final Object element,
final String property )
{
return false;
}
public void addListener( final ILabelProviderListener listener ) {}
public void removeListener( final ILabelProviderListener listener ) {}
}
private final class Sorter
extends ViewerSorter
{
public int compare( final Viewer viewer,
final Object a,
final Object b )
{
final IRuntime r1 = (IRuntime) a;
final IRuntime r2 = (IRuntime) b;
return r1.getLocalizedName().compareToIgnoreCase( r2.getLocalizedName() );
}
}
private final class RuntimeComponentsContentProvider
implements IStructuredContentProvider
{
public Object[] getElements( final Object element )
{
if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
{
return new Object[] { NO_RUNTIME_SELECTED_PLACEHOLDER };
}
else
{
final IRuntime r = (IRuntime) element;
return r.getRuntimeComponents().toArray();
}
}
public void dispose() { }
public void inputChanged( final Viewer viewer,
final Object oldObject,
final Object newObject ) {}
}
private final class RuntimeComponentsLabelProvider
implements ILabelProvider
{
private final ImageRegistry imageRegistry = new ImageRegistry();
public String getText( final Object element )
{
if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
{
return Resources.noRuntimeSelectedLabel;
}
final IRuntimeComponent comp = (IRuntimeComponent) element;
final IRuntimeComponentLabelProvider provider
= (IRuntimeComponentLabelProvider) comp.getAdapter( IRuntimeComponentLabelProvider.class );
if( provider == null )
{
final StringBuffer label = new StringBuffer();
label.append( comp.getRuntimeComponentType().getId() );
label.append( ' ' );
label.append( comp.getRuntimeComponentVersion().getVersionString() );
return label.toString();
}
else
{
return provider.getLabel();
}
}
public Image getImage( final Object element )
{
if( element == NO_RUNTIME_SELECTED_PLACEHOLDER )
{
return null;
}
final IRuntimeComponent rc = (IRuntimeComponent) element;
final IRuntimeComponentType rct = rc.getRuntimeComponentType();
final IRuntimeComponentVersion rcv = rc.getRuntimeComponentVersion();
final String key = rct.getId() + ":" + rcv.getVersionString(); //$NON-NLS-1$
Image image = this.imageRegistry.get( key );
if( image == null )
{
final IDecorationsProvider decprov
= (IDecorationsProvider) rcv.getAdapter( IDecorationsProvider.class );
this.imageRegistry.put( key, decprov.getIcon() );
image = this.imageRegistry.get( key );
}
return image;
}
public void dispose()
{
this.imageRegistry.dispose();
}
public boolean isLabelProperty( final Object element,
final String property )
{
return false;
}
public void addListener( final ILabelProviderListener listener ) {}
public void removeListener( final ILabelProviderListener listener ) {}
}
private static final class DecoratedRuntimeImageDescriptor
extends CompositeImageDescriptor
{
private static final String PRIMARY_RUNTIME_OVERLAY_IMG_LOCATION
= "images/primary-runtime-overlay.gif"; //$NON-NLS-1$
private static final ImageData PRIMARY_RUNTIME_OVERLAY
= FacetUiPlugin.getImageDescriptor( PRIMARY_RUNTIME_OVERLAY_IMG_LOCATION ).getImageData();
private static final String ERROR_OVERLAY_IMG_LOCATION
= "images/error-overlay.gif"; //$NON-NLS-1$
private static final ImageData ERROR_OVERLAY
= FacetUiPlugin.getImageDescriptor( ERROR_OVERLAY_IMG_LOCATION ).getImageData();
private static final String WARNING_OVERLAY_IMG_LOCATION
= "images/warning-overlay.gif"; //$NON-NLS-1$
private static final ImageData WARNING_OVERLAY
= FacetUiPlugin.getImageDescriptor( WARNING_OVERLAY_IMG_LOCATION ).getImageData();
private final ImageData base;
private final Point size;
private boolean isPrimary;
private IStatus valResult;
public DecoratedRuntimeImageDescriptor( final ImageDescriptor base,
final boolean isPrimary,
final IStatus valResult )
{
this.base = base.getImageData();
this.size = new Point( this.base.width, this.base.height );
this.isPrimary = isPrimary;
this.valResult = valResult;
}
protected void drawCompositeImage( final int width,
final int height )
{
drawImage( this.base, 0, 0 );
if( this.isPrimary )
{
drawImage( PRIMARY_RUNTIME_OVERLAY, width - PRIMARY_RUNTIME_OVERLAY.width,
height - PRIMARY_RUNTIME_OVERLAY.height );
}
if( this.valResult != null && ! this.valResult.isOK() )
{
final ImageData valOverlay
= this.valResult.getSeverity() == IStatus.ERROR
? ERROR_OVERLAY : WARNING_OVERLAY;
drawImage( valOverlay, 0, height - valOverlay.height );
}
}
protected Point getSize()
{
return this.size;
}
}
private final class ValidationProblemToolTip
extends BasicToolTip
{
public ValidationProblemToolTip( final Control control )
{
super( control );
}
@Override
protected Composite createToolTipContentArea( final Event event,
final Composite parent )
{
final IStatus validationResult = getValidationResult( event );
setMessage( validationResult.getMessage() );
return super.createToolTipContentArea( event, parent );
}
@Override
protected boolean shouldCreateToolTip( final Event event )
{
return ! getValidationResult( event ).isOK();
}
private IRuntime getRuntime( final Event event )
{
final TableItem item = getTableItem( event.x, event.y );
return item != null ? (IRuntime) item.getData() : null;
}
private IStatus getValidationResult( final Event event )
{
final IRuntime runtime = getRuntime( event );
IStatus result = null;
if( runtime != null )
{
result = RuntimesPanel.this.runtimeValidationAssistant.getValidationResult( runtime );
}
if( result == null )
{
result = Status.OK_STATUS;
}
return result;
}
}
private final class RuntimeValidationAssistant
{
private final Map<String,IStatus> validationResults;
private final IRuntimeLifecycleListener runtimeLifecycleListener;
public RuntimeValidationAssistant()
{
this.validationResults = new HashMap<String,IStatus>();
this.runtimeLifecycleListener = new IRuntimeLifecycleListener()
{
public void handleEvent( final IRuntimeLifecycleEvent event )
{
final IValidationStatusChangedEvent evt = (IValidationStatusChangedEvent) event;
setValidationResult( evt.getRuntime(), evt.getNewValidationStatus() );
handleRuntimeValidationResultChanged();
}
};
final Thread initialValidationThread = new Thread()
{
public void run()
{
for( IRuntime runtime : RuntimeManager.getRuntimes() )
{
final IStatus result = runtime.validate( new NullProgressMonitor() );
synchronized( RuntimeValidationAssistant.this.validationResults )
{
if( getValidationResult( runtime ) == null )
{
setValidationResult( runtime, result );
}
}
}
RuntimeManager.addListener( RuntimeValidationAssistant.this.runtimeLifecycleListener,
IRuntimeLifecycleEvent.Type.VALIDATION_STATUS_CHANGED );
handleRuntimeValidationResultChanged();
}
};
initialValidationThread.start();
}
public IStatus getValidationResult( final IRuntime runtime )
{
synchronized( this.validationResults )
{
return this.validationResults.get( runtime.getName() );
}
}
private void setValidationResult( final IRuntime runtime,
final IStatus validationResult )
{
synchronized( this.validationResults )
{
this.validationResults.put( runtime.getName(), validationResult );
}
}
public void dispose()
{
RuntimeManager.removeListener( this.runtimeLifecycleListener );
}
}
private static final class Resources
extends NLS
{
public static String runtimeCompositionLabel;
public static String makePrimaryLabel;
public static String newRuntimeButtonLabel;
public static String showAllRuntimes;
public static String noRuntimeSelectedLabel;
static
{
initializeMessages( RuntimesPanel.class.getName(),
Resources.class );
}
}
}