/* * 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.core; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import net.rim.ejde.internal.util.Messages; import net.rim.ide.core.IDEError; import net.rim.ide.core.ObjectsContentsHelper; import net.rim.ide.core.VarContentsHelper.Line; import org.apache.log4j.Logger; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.texteditor.ITextEditor; /** * This class defines some static utility methods. * */ public class RimIDEUtil implements IConstants { private static final Logger log = Logger.getLogger( RimIDEUtil.class ); /** * Creates the extension filter string, e.g. "*.java". * * @param ext * Extension string. * @return Extension filter string. */ public static String extensionFilterString( String ext ) { if( ( ext == null ) || ( ext.length() == 0 ) ) { return "*"; //$NON-NLS-1$ } if( ext.contains( ";" ) ) { return "*" + ext.replaceAll( ";", ";*" ); // adds * after ; } // delimeter if( ext.charAt( 0 ) == '.' ) { return "*" + ext; //$NON-NLS-1$ } return "*." + ext; //$NON-NLS-1$ } /** * Creates a physical file for <code>file<code> on the disk. * * @param file * A File instance. * @param shell * A Shell instance on which message dialogs will be displayed. * @return <code>true</code> the file is created correctly, <code>false</code> otherwise. */ public static boolean createFile( File file, Shell shell ) { File parent = file.getParentFile(); if( !parent.exists() ) { MessageBox messageBox = new MessageBox( shell, SWT.YES | SWT.NO ); messageBox.setMessage( "Create the folder " + parent.getPath() //$NON-NLS-1$ + " ?" ); //$NON-NLS-1$ if( messageBox.open() == SWT.YES ) { parent.mkdirs(); } } if( file.exists() ) { MessageBox messageBox = new MessageBox( shell, SWT.YES | SWT.NO ); messageBox.setMessage( "Overwrite the file " + file.getPath() + " ?" ); //$NON-NLS-1$ //$NON-NLS-2$ if( messageBox.open() == SWT.YES ) { file.delete(); } } try { return file.createNewFile(); } catch( IOException ioe ) { ioe.printStackTrace(); return false; } } /** * Opens a *.csv file for saving. * * @param shell * @return A *.csv file. */ public static File openCSVFileForSave( Shell shell ) { return RimIDEUtil.openFileForSave( shell, new String[] { RimIDEUtil.extensionFilterString( CSV_EXTENSION ) }, CSV_EXTENSION ); } /** * Opens a file for saving. * * @param shell * the shell * @param extensions * the extensions * @param forcedExtension * the forced extension * * @return A file. */ public static File openFileForSave( Shell shell, String[] extensions, String forcedExtension ) { return RimIDEUtil.openFileForSave( shell, null, extensions, forcedExtension ); } /** * Opens a file for saving. * * @param shell * the shell * @param file * the file * @param extensions * the extensions * * @return A file. */ public static File openFileForSave( Shell shell, String file, String[] extensions ) { return RimIDEUtil.openFile( shell, Messages.RimIDEUtil_SAVE_FILE_DIALOG_TITLE, file, SWT.SAVE, extensions, null ); } /** * Opens a file for saving. * * @param shell * the shell * @param file * the file * @param extensions * the extensions * @param forcedExtension * the forced extension * * @return A file. */ public static File openFileForSave( Shell shell, String file, String[] extensions, String forcedExtension ) { return RimIDEUtil.openFile( shell, Messages.RimIDEUtil_SAVE_FILE_DIALOG_TITLE, file, SWT.SAVE, extensions, forcedExtension ); } /** * Open a file through file dialog. * * @param shell * @param dialogTitle * @param file * @param purpose * @param extensions * @return */ public static File openFile( Shell shell, String dialogTitle, String file, int purpose, String[] extensions ) { return openFile( shell, dialogTitle, file, purpose, extensions, IConstants.EMPTY_STRING ); } /** * Open a file through file dialog. * * @param shell * @param dialogTitle * @param file * @param purpose * @param extensions * @return */ public static File openFile( Shell shell, String dialogTitle, String file, int purpose, String[] extensions, String forcedExtension ) { // create a file open dialog FileDialog fileDialog = new FileDialog( shell, purpose | SWT.SINGLE ); // set extension filter for( int i = 0; i < extensions.length; i++ ) { if( !extensions[ i ].contains( "*." ) ) { extensions[ i ] = "*." + extensions[ i ]; } } if( extensions.length != 0 ) { fileDialog.setFilterExtensions( extensions ); } // set default file name if( ( file != null ) && !file.trim().equals( EMPTY_STRING ) ) { fileDialog.setFileName( file ); } // set the title of the dialog fileDialog.setText( dialogTitle ); // open the dialog fileDialog.open(); // get selected file name String fileName = fileDialog.getFileName(); if( ( fileName == null ) || fileName.equals( "" ) ) { return null; } // get the parent path of selected file IPath fullPath = new Path( fileDialog.getFilterPath() + File.separator ); // add the filename fullPath = fullPath.append( fileName ); // add extension String currentExtension = fullPath.getFileExtension(); if( currentExtension == null || currentExtension.equals( IConstants.EMPTY_STRING ) ) { if( forcedExtension != null && !forcedExtension.equals( IConstants.EMPTY_STRING ) ) { fullPath = fullPath.addFileExtension( forcedExtension ); } } // create a File instance for the selected file File finalFile = new File( fullPath.toOSString() ); if( ( purpose == SWT.SAVE ) && !RimIDEUtil.createFile( finalFile, shell ) ) { return null; } return finalFile; } /** * Opens a directory dialog to choose a directory. * * @param shell * @param title * * @return A File which represents a directory. */ public static File openDirecotryDialog( Shell shell, String title ) { // create a file open dialog DirectoryDialog directoryDialog = new DirectoryDialog( shell, SWT.SINGLE ); // directoryDialog.setText( title ); // open the dialog String chosenDir = directoryDialog.open(); if( chosenDir == null ) { return null; } return new File( chosenDir ); } /** * Writes out the data of <code>table</code> to <code>file</code>. * * @param file * Destination file. * @param table * Table which will be written out to <code>file</code>. * * @throws IDEError */ public static void saveTableToFile( File file, Table table ) { if( ( file == null ) || !file.exists() ) { return; } if( table == null ) { return; } PrintStream out = null; try { out = new PrintStream( new FileOutputStream( file ) ); int cols = table.getColumnCount(); int rows = table.getItemCount(); // Print columnTitles for( int i = 0; i < cols; i++ ) { out.print( table.getColumn( i ).getText() ); if( i < ( cols - 1 ) ) { out.print( COMMA_MARK ); } } out.println(); // Get all lines and print data for( int i = 0; i < rows; i++ ) { TableItem item = table.getItem( i ); for( int j = 0; j < cols; j++ ) { out.print( item.getText( j ) ); if( j < ( cols - 1 ) ) { out.print( COMMA_MARK ); } } out.println(); } } catch( IOException fnf ) { fnf.printStackTrace(); } finally { if( out != null ) { out.close(); } } } /** * Writes out the data of <code>table</code> to <code>file</code> via the ObjectsContentsHelper. Necessary for tables that do * not set the text of the TableItem but circumvent this via the labelProvider. * * @param file * Destination file. * @param table * Table which will be written out to <code>file</code>. * @param helper * the ObjectsContentsHelper to grab the data required from the TableItem * * @throws IDEError */ public static void saveTableToFile( File file, Table table, ObjectsContentsHelper helper ) { if( ( file == null ) || !file.exists() ) { return; } if( table == null ) { return; } PrintStream out = null; try { out = new PrintStream( new FileOutputStream( file ) ); int cols = table.getColumnCount(); int rows = table.getItemCount(); // Print columnTitles for( int i = 0; i < cols; i++ ) { out.print( table.getColumn( i ).getText() ); if( i < ( cols - 1 ) ) { out.print( COMMA_MARK ); } } out.println(); // Get all lines and print data for( int i = 0; i < rows; i++ ) { TableItem item = table.getItem( i ); Line line; if( item.getData() != null ) { line = (Line) item.getData(); } else { line = helper.getLine( i ); } if( line == null ) { continue; } for( int j = 0; j < cols; j++ ) { // Fix for IDT 390741 - Replaced comma in string with // semicolon out.print( ( helper.getValue( line, j ) ).toString().replace( IConstants.COMMA_MARK, IConstants.SEMICOLON_MARK ) ); if( j < ( cols - 1 ) ) { out.print( COMMA_MARK ); } } out.println(); } } catch( IOException fnf ) { fnf.printStackTrace(); } finally { if( out != null ) { out.close(); } } } public static String parseResourceChangeEventType( int type ) { switch( type ) { case IResourceChangeEvent.POST_BUILD: return "post_build"; //$NON-NLS-1$ case IResourceChangeEvent.POST_CHANGE: return "post_change"; //$NON-NLS-1$ case IResourceChangeEvent.PRE_BUILD: return "pre_build"; //$NON-NLS-1$ case IResourceChangeEvent.PRE_CLOSE: return "pre_close"; //$NON-NLS-1$ case IResourceChangeEvent.PRE_DELETE: return "pre_delete"; //$NON-NLS-1$ default: return null; } } public static String parseResourceChangeEventType( IResourceChangeEvent event ) { if( event != null ) { return RimIDEUtil.parseResourceChangeEventType( event.getType() ); } return null; } public static String parseResourceDeltaKind( int kind ) { switch( kind ) { case IResourceDelta.ADDED: return "added"; //$NON-NLS-1$ case IResourceDelta.ADDED_PHANTOM: return "added_phantom"; //$NON-NLS-1$ case IResourceDelta.ALL_WITH_PHANTOMS: return "all_with_phantoms"; //$NON-NLS-1$ case IResourceDelta.CHANGED: return "changed"; //$NON-NLS-1$ case IResourceDelta.CONTENT: return "content"; //$NON-NLS-1$ case IResourceDelta.COPIED_FROM: return "copied_from"; //$NON-NLS-1$ case IResourceDelta.DESCRIPTION: return "description"; //$NON-NLS-1$ case IResourceDelta.ENCODING: return "encoding"; //$NON-NLS-1$ case IResourceDelta.MARKERS: return "markers"; //$NON-NLS-1$ case IResourceDelta.MOVED_FROM: return "moved_from"; //$NON-NLS-1$ case IResourceDelta.MOVED_TO: return "moved_to"; //$NON-NLS-1$ case IResourceDelta.NO_CHANGE: return "no_change"; //$NON-NLS-1$ case IResourceDelta.OPEN: return "open"; //$NON-NLS-1$ case IResourceDelta.REMOVED: return "removed"; //$NON-NLS-1$ case IResourceDelta.REMOVED_PHANTOM: return "removed_phantom"; //$NON-NLS-1$ case IResourceDelta.REPLACED: return "replaced"; //$NON-NLS-1$ case IResourceDelta.SYNC: return "sync"; //$NON-NLS-1$ case IResourceDelta.TYPE: return "type"; //$NON-NLS-1$ default: return null; } } public static String parseResourceType( int type ) { switch( type ) { case IResource.FILE: return "IResource.FILE"; //$NON-NLS-1$ case IResource.FOLDER: return "IResource.FOLDER"; //$NON-NLS-1$ case IResource.PROJECT: return "IResource.PROJECT"; //$NON-NLS-1$ case IResource.ROOT: return "IResource.ROOT"; //$NON-NLS-1$ default: return null; } } public static String parseResourceType( IResource resource ) { if( resource != null ) { return RimIDEUtil.parseResourceType( resource.getType() ); } return null; } /** * Generates regular expression from <code>string</code> * * @param string * @return regular expression string */ public static String generateRegex( String string ) { StringBuffer buffer = new StringBuffer(); for( int i = 0; i < string.length(); i++ ) { char singleChar = string.charAt( i ); if( singleChar == START_CHAR ) { // convert '*' to ".*" buffer.append( WILD_CAST_STRING ); } else if( singleChar == DOT_CHAR ) { // convert '.' to "\." buffer.append( DOT_QUOTE_STRING ); } else { buffer.append( singleChar ); } } return buffer.toString(); } /** * Gets a file that exists in an Eclipse project. * <p> * TODO: Someone can probably optimize this method better. Like using some of the IWorkspaceRoot.find*() methods... * * @param project * the Eclipse project the file belongs to * @param file * the File which is in the Eclipse project * @return the Eclipse resource file associated with the file */ public static IResource getResource( IProject project, File file ) { IJavaProject javaProject = JavaCore.create( project ); IPath filePath = new Path( file.getAbsolutePath() ); try { IClasspathEntry[] classpathEntries = javaProject.getResolvedClasspath( true ); IFile input = null; // Look for a source folder for( IClasspathEntry classpathEntry : classpathEntries ) { if( classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE ) { // Try to resolve the source container IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); IResource resource = workspaceRoot.findMember( classpathEntry.getPath() ); if( resource instanceof IContainer ) { try { IContainer sourceContainer = (IContainer) resource; File sourceContainerFile = EFS.getStore( resource.getLocationURI() ).toLocalFile( EFS.NONE, null ); IPath sourceFolderPath = new Path( sourceContainerFile.getAbsolutePath() ); // See if the file path is within this source folder // path if( sourceFolderPath.isPrefixOf( filePath ) ) { int segmentCount = sourceFolderPath.segmentCount(); IPath relativePath = filePath.removeFirstSegments( segmentCount ); input = sourceContainer.getFile( relativePath ); break; } } catch( CoreException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } } } return input; } catch( JavaModelException e ) { e.printStackTrace(); return null; } } /** * Open the source file represented by <code>fileStore</code> in an editor and highlight the line whose index is * <code>lineNumber</code>. * * @param fileStore * @param lineNumber */ static public void openSourceFile( IFileStore fileStore, int lineNumber ) { try { IWorkbenchWindow workbenchWindow = ContextManager.getActiveWorkbenchWindow(); IWorkbenchPage workbenchPage = workbenchWindow.getActivePage(); // open the source file in an editor IEditorPart editorPart = IDE.openEditorOnFileStore( workbenchPage, fileStore ); if( editorPart instanceof ITextEditor ) { ITextEditor textEditor = (ITextEditor) editorPart; IDocument document = textEditor.getDocumentProvider().getDocument( textEditor.getEditorInput() ); // get IRegion instance of the line IRegion region = document.getLineInformation( lineNumber - 1 ); // highlight line textEditor.setHighlightRange( region.getOffset(), region.getLength(), true ); } } catch( PartInitException e ) { log.error( e.getMessage() ); } catch( Exception exception ) { log.error( exception.getMessage() ); } } /** * Converts an array to a list. It will return <code>null</code> if the <code>objs</code> is null. * * @param objs * @return */ static public < T > List< T > convertToList( T[] objs ) { if( objs == null ) { return null; } List< T > list = new ArrayList< T >(); for( T obj : objs ) { list.add( obj ); } return list; } /** * Replace the "@" with "0x" in the given <code>string</code>. * * @param string * @return */ static public String convertAddressMark( String string ) { String convertedString = string.trim(); int index = convertedString.indexOf( "@" ); //$NON-NLS-1$ if( index == 0 ) { convertedString = "0x" + convertedString.substring( index + 1 ); //$NON-NLS-1$ } else if( index > 0 ) { convertedString = convertedString.substring( 0, index ) + "0x" + convertedString.substring( index + 1 ); //$NON-NLS-1$ } return convertedString; } }