package org.eclipse.gmf.tooling.runtime.parsers; import java.math.BigDecimal; import java.util.Date; import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.gmf.tooling.runtime.Messages; import org.eclipse.osgi.util.NLS; public abstract class AbstractAttributeParser extends AbstractFeatureParser { private String viewPattern; private String editorPattern; private String editPattern; protected final EAttribute[] features; protected final EAttribute[] editableFeatures; public AbstractAttributeParser(EAttribute[] features) { super(features); this.features = this.editableFeatures = features; } public AbstractAttributeParser(EAttribute[] features, EAttribute[] editableFeatures) { super(features, editableFeatures); this.features = features; this.editableFeatures = editableFeatures; } @Override protected Object getValue(EObject element, EStructuralFeature feature) { Object value = super.getValue(element, feature); Class<?> iClass = ((EAttribute) feature).getEAttributeType().getInstanceClass(); if (String.class.equals(iClass)) { if (value == null) { value = ""; //$NON-NLS-1$ } } return value; } @Override protected Object getValidNewValue(EStructuralFeature feature, Object value) { EClassifier type = feature.getEType(); if (false == type instanceof EDataType) { return value; } if (type instanceof EEnum) { return getValidEnumValue((EEnum) type, value); } if (value instanceof String) { try { return type.getEPackage().getEFactoryInstance().createFromString((EDataType) type, (String) value); } catch (Exception e) { String safeExceptionMsg = e == null || e.getMessage() == null ? "" : e.getMessage(); return new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_WrongStringConversion, type.getName(), safeExceptionMsg)); } } Class<?> iClass = type.getInstanceClass(); if (iClass == null) { //we can't say anything, just give up return value; } if (value == null) { return iClass.isPrimitive() ? new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_NullIsNotAllowed, type.getName())) : null; } if (Boolean.TYPE.equals(iClass) || Boolean.class.equals(iClass)) { return safeCast(value, type, Boolean.class); } if (Character.TYPE.equals(iClass) || Character.class.equals(iClass)) { return safeCast(value, type, Character.class); } if (Byte.TYPE.equals(iClass) || Byte.class.equals(iClass)) { return safeCastNumber(value, BYTE_CASTER); } if (Short.TYPE.equals(iClass) || Short.class.equals(iClass)) { return safeCastNumber(value, SHORT_CASTER); } if (Integer.TYPE.equals(iClass) || Integer.class.equals(iClass)) { return safeCastNumber(value, INT_CASTER); } if (Long.TYPE.equals(iClass) || Long.class.equals(iClass)) { return safeCastNumber(value, LONG_CASTER); } if (Float.TYPE.equals(iClass) || Float.class.equals(iClass)) { return safeCastNumber(value, FLOAT_CASTER); } if (Double.TYPE.equals(iClass) || Double.class.equals(iClass)) { return safeCastNumber(value, DOUBLE_CASTER); } if (Date.class.equals(iClass)) { return safeCast(value, type, Date.class); } if (BigDecimal.class.equals(iClass)) { if (value == null || value instanceof BigDecimal) { return value; } if (value instanceof Number) { return new BigDecimal(((Number) value).doubleValue()); } return new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_UnexpectedValueType, BigDecimal.class.getName())); } return value; } /** * @since 3.2 */ protected Object safeCast(Object value, EClassifier type, Class<?> clazz) { if (value == null) { return clazz.isPrimitive() ? new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_NullIsNotAllowed, type.getName())) : null; } return clazz.isInstance(value) ? clazz.cast(value) : new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_UnexpectedValueType, clazz.getName())); } /** * @since 3.2 */ protected <T extends Number> Object safeCastNumber(Object value, NumberCaster<T> caster) { if (value instanceof Number) { return caster.castNumber((Number) value); } return new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_UnexpectedValueType, Number.class.getName())); } /** * @since 3.2 */ protected Object getValidEnumValue(EEnum type, Object value) { EEnumLiteral literal = null; if (value instanceof String) { literal = type.getEEnumLiteralByLiteral((String) value); } else if (value instanceof Number) { literal = type.getEEnumLiteral(((Number) value).intValue()); } else if (value instanceof Enumerator) { literal = type.getEEnumLiteral(((Enumerator) value).getValue()); } return literal == null ? new InvalidValue(NLS.bind(Messages.AbstractAttributeParser_UnknownLiteral, value)) : literal.getInstance(); } public String getViewPattern() { return viewPattern; } public void setViewPattern(String viewPattern) { this.viewPattern = viewPattern; } public String getEditorPattern() { return editorPattern; } public void setEditorPattern(String editorPattern) { this.editorPattern = editorPattern; } public String getEditPattern() { return editPattern; } public void setEditPattern(String editPattern) { this.editPattern = editPattern; } private static abstract class NumberCaster<T extends Number> { public abstract T castNumber(Number number); } private static NumberCaster<Short> SHORT_CASTER = new NumberCaster<Short>() { @Override public Short castNumber(Number number) { return number instanceof Short ? (Short) number : number.shortValue(); } }; private static NumberCaster<Byte> BYTE_CASTER = new NumberCaster<Byte>() { @Override public Byte castNumber(Number number) { return number instanceof Byte ? (Byte) number : number.byteValue(); } }; private static NumberCaster<Integer> INT_CASTER = new NumberCaster<Integer>() { @Override public Integer castNumber(Number number) { return number instanceof Integer ? (Integer) number : number.intValue(); } }; private static NumberCaster<Long> LONG_CASTER = new NumberCaster<Long>() { @Override public Long castNumber(Number number) { return number instanceof Long ? (Long) number : number.longValue(); } }; private static NumberCaster<Double> DOUBLE_CASTER = new NumberCaster<Double>() { @Override public Double castNumber(Number number) { return number instanceof Double ? (Double) number : number.doubleValue(); } }; private static NumberCaster<Float> FLOAT_CASTER = new NumberCaster<Float>() { @Override public Float castNumber(Number number) { return number instanceof Float ? (Float) number : number.floatValue(); } }; }