package org.teiid.designer.ui.properties;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.ui.provider.PropertyDescriptor.EDataTypeCellEditor;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.teiid.designer.metamodels.relational.RelationalPackage;
import org.teiid.designer.ui.UiConstants;
/**
* An {@link IPropertyEditorFactory} that converts numbers bigger than {@link Integer#MAX_VALUE} into a negative integer
* for storage. And reverses the process for retrieval. The only negative number not converted is -1.
*/
public class FloatAsIntPropertyEditorFactory implements IPropertyEditorFactory {
private static final Collection<EStructuralFeature> FLOAT_AS_INT_FEATURES =
Collections.unmodifiableCollection(Arrays.asList(new EStructuralFeature[] {
RelationalPackage.eINSTANCE.getTable_Cardinality(),
RelationalPackage.eINSTANCE.getColumn_DistinctValueCount(),
RelationalPackage.eINSTANCE.getColumn_NullValueCount()
}));
/**
* @param feature the feature being checked (cannot be <code>null</code>)
* @return <code>true</code> if the feature is supported by this editor factory
*/
public static boolean supports(final EStructuralFeature feature) {
return FLOAT_AS_INT_FEATURES.contains(feature);
}
/**
* Converts negative values (other than -1) to positive for display.
*/
public static final LabelProvider LABEL_PROVIDER = new LabelProvider() {
@Override
public String getText(final Object element) {
if (element instanceof Integer) {
final int value = (Integer)element;
if (value >= -1) {
return Integer.toString(value);
}
final float floatValue = Float.intBitsToFloat(value & 0x7fffffff);
return String.valueOf(floatValue);
}
return super.getText(element);
}
};
@Override
public CellEditor createPropertyEditor(final Composite composite,
final IItemPropertyDescriptor itemPropertyDescriptor,
final IPropertyDescriptor propertyDescriptor,
final Object object) {
final EStructuralFeature feature = (EStructuralFeature)itemPropertyDescriptor.getFeature(object);
final EDataType dataType = (EDataType)feature.getEType();
return new Editor(dataType, composite);
}
@Override
public boolean supportsStructuralFeature(final EStructuralFeature feature) {
return supports(feature);
}
private class Editor extends EDataTypeCellEditor {
private Editor(final EDataType dataType,
final Composite parent) {
super(dataType, parent);
setValidator(new Validator());
}
@Override
public Object doGetValue() {
final String valueAsText = text.getText();
final long value = Long.parseLong(valueAsText);
if ((value == -1) || (value < 0)) {
return -1;
}
if (value <= Integer.MAX_VALUE) {
return (int)value;
}
return (Float.floatToRawIntBits(value) | 0x80000000);
}
@Override
public void doSetValue(final Object value) {
final String valueAsText = LABEL_PROVIDER.getText(value);
super.doSetValue(valueAsText);
}
}
private static class Validator implements ICellEditorValidator, IInputValidator {
@Override
public String isValid(final String newText) {
return isValid((Object)newText);
}
@Override
public String isValid(final Object object) {
try {
final long value = Long.parseLong(object.toString());
if (value < -1) {
return UiConstants.Util.getString("FloatAsIntPropertyEditorFactory.invalidValue"); //$NON-NLS-1$
}
return null;
} catch (final Exception e) {
String message = e.getClass().getName();
final int index = message.lastIndexOf('.');
if (index >= 0) {
message = message.substring(index + 1);
}
if (e.getLocalizedMessage() != null) {
message = message + ": " + e.getLocalizedMessage(); //$NON-NLS-1$
}
return message;
}
}
}
}