/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.model.ui; import java.io.File; import java.net.URL; import java.util.Iterator; import net.rim.ejde.internal.model.ui.LibraryContentProvider.SubElement; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; import org.eclipse.jdt.debug.ui.launchConfigurations.AbstractVMInstallPage; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.jdt.internal.debug.ui.jres.JREMessages; import org.eclipse.jdt.internal.launching.EEVMInstall; import org.eclipse.jdt.internal.launching.EEVMType; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.LibraryLocation; import org.eclipse.jdt.launching.VMStandin; import org.eclipse.jdt.launching.environments.ExecutionEnvironmentDescription; import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; /** * Control used to edit the libraries associated with a VM install */ public class VMLibraryBlock extends AbstractVMInstallPage implements SelectionListener, ISelectionChangedListener { /** * Attribute name for the last path used to open a file/directory chooser dialog. */ protected static final String LAST_PATH_SETTING = "LAST_PATH_SETTING"; //$NON-NLS-1$ /** * the prefix for dialog setting pertaining to this block */ protected static final String DIALOG_SETTINGS_PREFIX = "VMLibraryBlock"; //$NON-NLS-1$ protected boolean fInCallback = false; protected VMStandin fVmInstall; // widgets protected LibraryContentProvider fLibraryContentProvider; protected TreeViewer fLibraryViewer; private Button fUpButton; private Button fDownButton; private Button fRemoveButton; private Button fAddButton; private Button fJavadocButton; private Button fSourceButton; protected Button fDefaultButton; private IStatus[] fLibStatus; /** * Constructs a new wizard page with the given name. * * @param pageName * page name */ public VMLibraryBlock() { super( JREMessages.VMLibraryBlock_2 ); fLibStatus = new IStatus[] { Status.OK_STATUS }; } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl( Composite parent ) { Font font = parent.getFont(); Composite comp = SWTFactory.createComposite( parent, font, 2, 1, GridData.FILL_BOTH, 0, 0 ); fLibraryViewer = new TreeViewer( comp ); GridData gd = new GridData( GridData.FILL_BOTH ); gd.heightHint = 6; fLibraryViewer.getControl().setLayoutData( gd ); fLibraryContentProvider = new LibraryContentProvider(); fLibraryViewer.setContentProvider( fLibraryContentProvider ); fLibraryViewer.setLabelProvider( new LibraryLabelProvider() ); fLibraryViewer.setInput( this ); fLibraryViewer.addSelectionChangedListener( this ); Composite pathButtonComp = SWTFactory.createComposite( comp, font, 1, 1, GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL, 0, 0 ); fAddButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_7, JREMessages.VMLibraryBlock_16, null ); fAddButton.addSelectionListener( this ); fJavadocButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_3, JREMessages.VMLibraryBlock_17, null ); fJavadocButton.setEnabled( false ); fJavadocButton.addSelectionListener( this ); fSourceButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_11, JREMessages.VMLibraryBlock_18, null ); fSourceButton.setEnabled( false ); fSourceButton.addSelectionListener( this ); fLibraryViewer.addDoubleClickListener( new IDoubleClickListener() { public void doubleClick( DoubleClickEvent event ) { IStructuredSelection sel = (IStructuredSelection) event.getViewer().getSelection(); Object obj = sel.getFirstElement(); if( obj instanceof SubElement ) { edit( sel, ( (SubElement) obj ).getType() ); } } } ); fRemoveButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_6, JREMessages.VMLibraryBlock_12, null ); fRemoveButton.setEnabled( false ); fRemoveButton.addSelectionListener( this ); fUpButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_4, JREMessages.VMLibraryBlock_13, null ); fUpButton.setEnabled( false ); fUpButton.addSelectionListener( this ); fDownButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_5, JREMessages.VMLibraryBlock_14, null ); fDownButton.setEnabled( false ); fDownButton.addSelectionListener( this ); fDefaultButton = SWTFactory.createPushButton( pathButtonComp, JREMessages.VMLibraryBlock_9, JREMessages.VMLibraryBlock_15, null ); fDefaultButton.addSelectionListener( this ); setControl( comp ); } /** * The "default" button has been toggled */ private void restoreDefaultLibraries() { LibraryLocation[] libs = null; File installLocation = null; if( fVmInstall != null ) { if( EEVMType.ID_EE_VM_TYPE.equals( fVmInstall.getVMInstallType().getId() ) ) { File definitionFile = null; String path = fVmInstall.getAttribute( EEVMInstall.ATTR_DEFINITION_FILE ); if( path != null ) { definitionFile = new File( path ); } if( definitionFile != null ) { try { ExecutionEnvironmentDescription desc = new ExecutionEnvironmentDescription( definitionFile ); libs = desc.getLibraryLocations(); } catch( CoreException e ) { libs = new LibraryLocation[ 0 ]; } } else { libs = new LibraryLocation[ 0 ]; } } else { installLocation = fVmInstall.getInstallLocation(); if( installLocation == null ) { libs = new LibraryLocation[ 0 ]; } else { libs = fVmInstall.getVMInstallType().getDefaultLibraryLocations( installLocation ); } } fLibraryContentProvider.setLibraries( libs ); } update(); } /** * Updates buttons and status based on current libraries */ private void update() { updateButtons(); IStatus status = Status.OK_STATUS; if( fLibraryContentProvider.getLibraries().length == 0 ) { status = new Status( IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Libraries cannot be empty.", null ); //$NON-NLS-1$ } LibraryStandin[] standins = fLibraryContentProvider.getStandins(); for( int i = 0; i < standins.length; i++ ) { IStatus st = standins[ i ].validate(); if( !st.isOK() ) { status = st; break; } } fLibStatus[ 0 ] = status; if( status.isOK() ) { setErrorMessage( null ); setPageComplete( true ); } else { setErrorMessage( status.getMessage() ); setPageComplete( false ); } // must force since this page is a 'sub-page' and may not be considered the current page if( getContainer().getCurrentPage() != this ) { getContainer().updateMessage(); getContainer().updateButtons(); } } /** * Determines if the current libraries displayed to the user are the default location for the given vm working copy. * * @param vm * the virtual machine to check for the default location * @return true if the current set of locations are the defaults, false otherwise */ protected boolean isDefaultLocations( IVMInstall vm ) { LibraryLocation[] libraryLocations = fLibraryContentProvider.getLibraries(); if( vm == null || libraryLocations == null ) { return true; } File installLocation = vm.getInstallLocation(); if( installLocation != null ) { LibraryLocation[] def = vm.getVMInstallType().getDefaultLibraryLocations( installLocation ); if( def.length == libraryLocations.length ) { for( int i = 0; i < def.length; i++ ) { if( !def[ i ].equals( libraryLocations[ i ] ) ) { return false; } } return true; } } return false; } /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected( SelectionEvent e ) { Object source = e.getSource(); if( source == fUpButton ) { fLibraryContentProvider.up( (IStructuredSelection) fLibraryViewer.getSelection() ); } else if( source == fDownButton ) { fLibraryContentProvider.down( (IStructuredSelection) fLibraryViewer.getSelection() ); } else if( source == fRemoveButton ) { fLibraryContentProvider.remove( (IStructuredSelection) fLibraryViewer.getSelection() ); } else if( source == fAddButton ) { add( (IStructuredSelection) fLibraryViewer.getSelection() ); } else if( source == fJavadocButton ) { edit( (IStructuredSelection) fLibraryViewer.getSelection(), SubElement.JAVADOC_URL ); } else if( source == fSourceButton ) { edit( (IStructuredSelection) fLibraryViewer.getSelection(), SubElement.SOURCE_PATH ); } else if( source == fDefaultButton ) { restoreDefaultLibraries(); } update(); } /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected( SelectionEvent e ) { } /** * Open the file selection dialog, and add the return jars as libraries. */ private void add( IStructuredSelection selection ) { IDialogSettings dialogSettings = JDIDebugUIPlugin.getDefault().getDialogSettings(); String lastUsedPath = dialogSettings.get( LAST_PATH_SETTING ); if( lastUsedPath == null ) { lastUsedPath = ""; //$NON-NLS-1$ } FileDialog dialog = new FileDialog( fLibraryViewer.getControl().getShell(), SWT.MULTI ); dialog.setText( JREMessages.VMLibraryBlock_10 ); dialog.setFilterExtensions( new String[] { "*.jar;*.zip", "*.*" } ); //$NON-NLS-1$ //$NON-NLS-2$ dialog.setFilterPath( lastUsedPath ); String res = dialog.open(); if( res == null ) { return; } String[] fileNames = dialog.getFileNames(); int nChosen = fileNames.length; IPath filterPath = new Path( dialog.getFilterPath() ); LibraryLocation[] libs = new LibraryLocation[ nChosen ]; for( int i = 0; i < nChosen; i++ ) { libs[ i ] = new LibraryLocation( filterPath.append( fileNames[ i ] ).makeAbsolute(), Path.EMPTY, Path.EMPTY ); } dialogSettings.put( LAST_PATH_SETTING, filterPath.toOSString() ); fLibraryContentProvider.add( libs, selection ); } /** * Open the javadoc location dialog or the source location dialog, and set the result to the selected libraries. */ private void edit( IStructuredSelection selection, int type ) { Object obj = selection.getFirstElement(); LibraryStandin standin = null; if( obj instanceof LibraryStandin ) { standin = (LibraryStandin) obj; } else if( obj instanceof SubElement ) { SubElement sub = (SubElement) obj; standin = sub.getParent(); } if( standin != null ) { LibraryLocation library = standin.toLibraryLocation(); if( type == SubElement.JAVADOC_URL ) { URL[] urls = BuildPathDialogAccess.configureJavadocLocation( fLibraryViewer.getControl().getShell(), library .getSystemLibraryPath().toOSString(), library.getJavadocLocation() ); if( urls != null ) { fLibraryContentProvider.setJavadoc( urls[ 0 ], selection ); } } else if( type == SubElement.SOURCE_PATH ) { IRuntimeClasspathEntry entry = JavaRuntime.newArchiveRuntimeClasspathEntry( library.getSystemLibraryPath() ); entry.setSourceAttachmentPath( library.getSystemLibrarySourcePath() ); entry.setSourceAttachmentRootPath( library.getPackageRootPath() ); IClasspathEntry classpathEntry = BuildPathDialogAccess.configureSourceAttachment( fLibraryViewer.getControl() .getShell(), entry.getClasspathEntry() ); if( classpathEntry != null ) { fLibraryContentProvider.setSourcePath( classpathEntry.getSourceAttachmentPath(), classpathEntry.getSourceAttachmentRootPath(), selection ); } } } } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) */ public void selectionChanged( SelectionChangedEvent event ) { updateButtons(); } /** * Refresh the enable/disable state for the buttons. */ private void updateButtons() { IStructuredSelection selection = (IStructuredSelection) fLibraryViewer.getSelection(); fRemoveButton.setEnabled( !selection.isEmpty() ); boolean enableUp = true, enableDown = true, allSource = true, allJavadoc = true, allRoots = true; Object[] libraries = fLibraryContentProvider.getElements( null ); if( selection.isEmpty() || libraries.length == 0 ) { enableUp = false; enableDown = false; } else { Object first = libraries[ 0 ]; Object last = libraries[ libraries.length - 1 ]; for( Iterator iter = selection.iterator(); iter.hasNext(); ) { Object element = iter.next(); Object lib; if( element instanceof SubElement ) { allRoots = false; SubElement subElement = (SubElement) element; lib = ( subElement ).getParent().toLibraryLocation(); if( subElement.getType() == SubElement.JAVADOC_URL ) { allSource = false; } else { allJavadoc = false; } } else { lib = element; allSource = false; allJavadoc = false; } if( lib == first ) { enableUp = false; } if( lib == last ) { enableDown = false; } } } fUpButton.setEnabled( enableUp ); fDownButton.setEnabled( enableDown ); fJavadocButton.setEnabled( !selection.isEmpty() && ( allJavadoc || allRoots ) ); fSourceButton.setEnabled( !selection.isEmpty() && ( allSource || allRoots ) ); } /* * (non-Javadoc) * * @see org.eclipse.jdt.debug.ui.launchConfigurations.AbstractVMInstallPage#finish() */ public boolean finish() { if( fVmInstall != null ) { if( isDefaultLocations( fVmInstall ) ) { fVmInstall.setLibraryLocations( null ); } else { LibraryLocation[] libs = fLibraryContentProvider.getLibraries(); fVmInstall.setLibraryLocations( libs ); } } return true; } /* * (non-Javadoc) * * @see org.eclipse.jdt.debug.ui.launchConfigurations.AbstractVMInstallPage#getSelection() */ public VMStandin getSelection() { return fVmInstall; } /* * (non-Javadoc) * * @see org.eclipse.jdt.debug.ui.launchConfigurations.AbstractVMInstallPage#setSelection(org.eclipse.jdt.launching.VMStandin) */ public void setSelection( VMStandin vm ) { super.setSelection( vm ); LibraryLocation[] libraryLocations = null; if( vm == null ) { libraryLocations = new LibraryLocation[ 0 ]; } else { libraryLocations = JavaRuntime.getLibraryLocations( vm ); } fVmInstall = vm; fLibraryContentProvider.setLibraries( libraryLocations ); } /* * (non-Javadoc) * * @see org.eclipse.jdt.debug.ui.launchConfigurations.AbstractVMInstallPage#getVMStatus() */ protected IStatus[] getVMStatus() { return fLibStatus; } }