/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* 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
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Mathias Stuempert - initial API and implementation
*****************************************************************************/
package eu.geclipse.ui.providers;
import java.net.URL;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import eu.geclipse.ui.internal.Activator;
/**
* Label provider for tables that handles {@link IFileStore}s. The columns are
* configurable.
*/
public class FileStoreLabelProvider
extends LabelProvider
implements ITableLabelProvider {
/**
* Type field for the name column.
*/
public static final String COLUMN_TYPE_NAME = "NAME"; //$NON-NLS-1$
/**
* Type field for the size column.
*/
public static final String COLUMN_TYPE_SIZE = "SIZE"; //$NON-NLS-1$
/**
* Type field for the modification date column.
*/
public static final String COLUMN_TYPE_MOD_DATE = "MOD_DATE"; //$NON-NLS-1$
/**
* Empty string definition.
*/
protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
/**
* Not available definition.
*/
protected static final String NA_STRING = "N/A"; //$NON-NLS-1$
/**
* Prefixes for the magnitude of the file size.
*/
private static final String[] prefixes = {
"", //$NON-NLS-1$
"k", //$NON-NLS-1$
"M", //$NON-NLS-1$
"G", //$NON-NLS-1$
"T", //$NON-NLS-1$
"P", //$NON-NLS-1$
"E" //$NON-NLS-1$
};
/**
* Unit of the file size, i.e. B for bytes.
*/
private static final String FILE_SIZE_UNIT = "B"; //$NON-NLS-1$
/**
* Format string for the file size format.
*/
private static final String FILE_SIZE_FORMAT = "0.#"; //$NON-NLS-1$
/**
* Cache for all used images.
*/
private static Hashtable< String, Image > images;
/**
* Date format used to format the modification time.
*/
private DateFormat dateFormat;
/**
* Decimal format used to format file sizes.
*/
private DecimalFormat sizeFormat;
/**
* Column configuration map.
*/
private Hashtable< Integer, String > columnMap;
/**
* Create a new <code>ConnectionViewLabelProvider</code>
*/
public FileStoreLabelProvider() {
this.dateFormat = new SimpleDateFormat();
this.sizeFormat = new DecimalFormat( FILE_SIZE_FORMAT );
}
/**
* Add a new column of the specified type to this provider. Any former
* column at the specified index is discarded.
*
* @param index The index of the new column.
* @param type The type of the new column, i.e. one of the
* COLUMN_TYPE_* fields.
*/
public void addColumn( final int index, final String type ) {
if ( this.columnMap == null ) {
this.columnMap = new Hashtable< Integer, String >();
}
this.columnMap.put( Integer.valueOf( index ), type );
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
*/
public Image getColumnImage( final Object element,
final int columnIndex ) {
Image result = null;
if ( element instanceof IFileStore ) {
result = getColumnImage( ( IFileStore ) element, columnIndex );
} else if ( element instanceof IAdaptable ) {
IFileStore adapter = ( IFileStore ) ( ( IAdaptable ) element ).getAdapter( IFileStore.class );
if ( adapter != null ) {
result = getColumnImage( adapter, columnIndex );
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
*/
public String getColumnText( final Object element,
final int columnIndex ) {
String result = null;
if ( element instanceof IFileStore ) {
result = getColumnText( ( IFileStore ) element, columnIndex );
} else if ( element instanceof IAdaptable ) {
IFileStore adapter = ( IFileStore ) ( ( IAdaptable ) element ).getAdapter( IFileStore.class );
if ( adapter != null ) {
result = getColumnText( adapter, columnIndex );
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
*/
@Override
public Image getImage( final Object element ) {
return getColumnImage( element, 0 );
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
*/
@Override
public String getText( final Object element ) {
return getColumnText( element, 0 );
}
/**
* Get the image for the specified file store and column.
*
* @param fileStore The file store.
* @param columnIndex The 0-based column index.
* @return The image or <code>null</code>.
*/
protected Image getColumnImage( final IFileStore fileStore,
final int columnIndex ) {
Image result = null;
if ( columnIndex == 0 ) {
IFileInfo info = fileStore.fetchInfo();
if ( info.isDirectory() ) {
result = getFolderImage();
} else {
result = getFileImage();
}
}
return result;
}
/**
* Get the text for the specified file store and column.
*
* @param fileStore The file store.
* @param columnIndex The 0-based column index.
* @return The text that may be an empty string.
*/
protected String getColumnText( final IFileStore fileStore,
final int columnIndex ) {
String result = EMPTY_STRING;
String type = getColumnType( columnIndex );
if ( COLUMN_TYPE_NAME.equals( type ) ) {
result = getName( fileStore );
} else if ( COLUMN_TYPE_SIZE.equals( type ) ) {
result = getSize( fileStore );
} else if ( COLUMN_TYPE_MOD_DATE.equals( type ) ) {
result = getModificationDate( fileStore );
}
return result;
}
/**
* Get the type of the specified column or <code>null</code> if no
* such column is defined.
*
* @param columnIndex The 0-based column index.
* @return The column's type or <code>null</code>.
*/
protected String getColumnType( final int columnIndex ) {
String result = null;
if ( this.columnMap != null ) {
result = this.columnMap.get( Integer.valueOf( columnIndex ) );
}
return result;
}
/**
* Convert the specified time to a readable string.
*
* @param time Seconds since 1.1.1970, i.e. Unix time.
* @return A string representation of the date.
*/
protected String convertTimeToString( final long time ) {
String result = NA_STRING;
if ( time != EFS.NONE ) {
Date date = new Date( time );
result = this.dateFormat.format( date );
}
return result;
}
/**
* Convert the specified size to a readable string.
*
* @param size The size in byte.
* @return A string representation of the size.
*/
protected String convertSizeToString( final long size ) {
String result = NA_STRING;
if ( size == 0 ) {
result = "0 " + FILE_SIZE_UNIT; //$NON-NLS-1$
} else if ( size > 0 ) {
double mag = Math.floor( Math.log( size ) / Math.log( 1024 ) );
if ( mag >= prefixes.length ) mag = prefixes.length - 1;
double ref = Math.pow( 1024., mag );
double value = size / ref;
/*
* The DecimalFormat.format() method rounds the number up if necessary.
* So we will end up with "1024 kB" if the file is a few Bytes smaller than
* 1024 kB... What do other tools do?
*/
result
= this.sizeFormat.format( value )
+ " " + prefixes[ ( int ) mag ] + FILE_SIZE_UNIT; //$NON-NLS-1$
}
return result;
}
/**
* Get the properly formatted string representing the time of
* the last modification for the specified {@link IFileStore}.
*
* @param fileStore The {@link IFileStore} for which to create a
* modification string.
* @return The properly formatted modification string.
*/
protected String getModificationDate( final IFileStore fileStore ) {
String result = NA_STRING;
if ( fileStore != null ) {
result = convertTimeToString( fileStore.fetchInfo().getLastModified() );
}
return result;
}
/**
* Get a user-friendly name for the specified file store. May be overwritten
* by sub classes.
*
* @param fileStore The file store.
* @return A name for the file store.
*/
protected String getName( final IFileStore fileStore ) {
return fileStore.getName();
}
/**
* Get the properly formatted string representing the file size
* for the specified {@link IFileStore}.
*
* @param fileStore The {@link IFileStore} for which to create a
* file size string.
* @return The properly formatted file size string.
*/
protected String getSize( final IFileStore fileStore ) {
String result = NA_STRING;
if ( fileStore != null ) {
if ( fileStore.fetchInfo().isDirectory() ) {
result = EMPTY_STRING;
} else {
result = convertSizeToString( fileStore.fetchInfo().getLength() );
}
}
return result;
}
/**
* Get a standard image for files.
*
* @return {@link ISharedImages#IMG_OBJ_FILE}
*/
protected static Image getFileImage() {
return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE );
}
/**
* Get a standard image for folders.
*
* @return {@link ISharedImages#IMG_OBJ_FOLDER}
*/
protected static Image getFolderImage() {
return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER );
}
/**
* Get the image at the specified path. The image is cached internally and
* when requested again the cached image is returned.
*
* @param path The path of the image.
* @return The image itself or <code>null</code> if no image could be found
* at the specified path.
*/
protected static Image getImage( final String path ) {
Image result = null;
if ( images == null ) {
images = new Hashtable< String, Image >();
} else {
result = images.get( path );
}
if ( result == null ) {
result = loadImage( path );
images.put( path, result );
}
return result;
}
/**
* Load the image from the specified path.
*
* @param path The path of the image.
* @return The image or <code>null</code> if no image could be found
* at the specified path.
*/
protected static Image loadImage( final String path ) {
URL url = Activator.getDefault().getBundle().getEntry( path );
ImageDescriptor descriptor = ImageDescriptor.createFromURL( url );
return descriptor.createImage();
}
}