Cmobilecom AF 5.19 Developer Guide

15.1 Data Conversions

User input of a property value is a string that needs to be converted to the property type before updating the property value.

Built-in Conversions

The following types have built-in data conversions: In addition to built-in conversions, custom converters are supported.

Number with Format

If a property type is a Number with a defined format, then data conversion is based on its number format. For example,

    @Property(name="expense",
        renderStyle=@RenderStyleDef(number=@NumberDesc(type=NumberDescriptor.Type.CURRENCY)))       

    @Property(name="quantity",
        renderStyle=@RenderStyleDef(number=@NumberDesc(type=NumberDescriptor.Type.NUMBER,
            minFractionDigits=0, maxFractionDigits=0)))       
 
    @Property(name="rate",
        renderStyle=@RenderStyleDef(number=@NumberDesc(type=NumberDescriptor.Type.PERCENT,
            minFractionDigits=0, maxFractionDigits=3)))
Number type can be CURRENCY, NUMBER, PERCENT or NO_FORMAT, and number format is locale sensitive. If number type is NumberDescriptor.Type.NO_FORMAT(default), then constructor will be used to convert user input to number. see section: Other Types.

Enum

For enum types, names(not ordinal values) are used for conversion. For example,

public enum Color {
	RED,
	GREEN,
	BLUE
}
The string value "RED" is converted to Color.RED.

Date/Timestamp

The DateFormat for java.util.Date is SHORT for date, and MEDIUM for time. It is locale sensitive. Take en-US locale for instance, M/d/yyyy for date, and M/d/yyyy H:mm:ss for timestamp. For example, 12/18/2022, 12/18/2022 15:30:50.

Timestamp is converted to/from string using the time zone specified in the Parameters of the DataAccessUnit.

TemporalAccessor

Similar to java.util.Date, the DateTimeFormat for TemporalAccessor such as LocalDate and LocalDateTime is SHORT for date, and MEDIUM for time. But it does not have time zone attached.

Locale

java.util.Locale is mapped to its LanguageTag. For example, en-US, zh, zh-Hans.

ReportPeriod

Report period such as 2022 (year), 2022-M10 (the 10th Month of year 2022), 2022-Q1 (the first Quarter of year 2022), 2022-D123 (the 123th day of year 2022) or M/d/yyyy (one specific day, locale sensitive format). Except for M/d/yyyy format, the actual date period for a ReportPeriod is based on Year Start Date (calendar or fiscal year) that is set in the Parameters of the DataAccessUnit.

Persistence Entity

For persistence entities, user input must start with a primary or unique key, optionally followed by descriptive text with forward slash separator. The primary/unique key is used to retrieve entity from persistence.

Other Types

For types other than above, a constructor with a string parameter is expected. The constructor is used to create an instance from user input. For example,

Primitive types:


	new Integer(text);
User-defined types:

	public class Color {
		private String name;
		
		public Color(String name) {
			this.name = name;
		}
	}

Collection

For a collection, user input must be a List of member values(String) or a string with comma-separated member values. Member values are converted based on member types in the same way as property singular-value conversion.

Example 1: collection of enum values


public enum Color {
	RED,
	GREEN,
	BLUE
}
Property type is a List<Color>. User input must be a list of string: for example, {"RED", "BLUE", "GREEN"}, or a string: "RED,BLUE,GREEN". The member string values will be converted to Color enum values.

Example 2: collection of persistence entities


@Entity(name="Employee")
public class Employee extends PersistenceEntityBase implements NormativeId {

}
Property type is a Set<Employee>. User input must be a list of employee nid(s): for example, {"011", "012", "025"}, or a string: "011,012,025". The member nid values will be used to retrieve Employee entities from persistence.

With autoComplete enabled, a list of suggestions will be shown while user is typing. Or open input dialog, user can create new entities or select existing entities.

Select Items

Property select items is used for such render styles as Select One and Select Many. SelectItem values must be string that will be converted to property type during model update.

	@Override
	public List<SelectItem> getPropertySelectItems(EntityProperty<T> property) throws SystemException {
		// The values of select items must be String
	}
  
	@Override
	public List<SelectItem> getDynamicSelectItems(PersistenceDataBackingBean<T> backingBean, 
  		T entity, EntityProperty<T> property) throws SystemException {
		// The values of select items must be String
	}
To add empty selection:

	SelectItemListProvider.addEmptySelection(selectItems, "Select one", true);
Empty selection will be converted to NULL value.

Class SelectItemListProvider provides built-in select items such as for currency, locale and time zone. SelectItem labels are of I18NName type, which will be translated from resource bundles during render phase.

Custom Converter

If a property is annotated with a converter, for example,

	@Property(name="serialNumber", view={ViewType.ENTITY},
		converter=SerialNumberConverter.class)
The property value will be converted by the converter for both display and update. The following SerialNumberConverter splits a serial number into groups for readability, and removes grouping for update.

public class SerialNumberConverter<T extends PersistenceEntity> implements ValueConverter<T>, Serializable {

	@Override
	public Object getValueAsObject(EntityProperty<T> ep, String value) throws SystemException {
		if (value == null)
			return null;
		
		// remove separator -
		return value.replaceAll("-", "");
	}

	@Override
	public String getValueAsString(EntityProperty<T> ep, T entity) throws SystemException {
		// split into groups of 4 chars
		String value = (String)ep.getValue(entity);
		if (value == null)
			return null;
		
		int len = value.length();
		StringBuilder sb = new StringBuilder();
		for (int i=0; i<len; i++) {
			if (i>0 && i % 4 == 0)
				sb.append('-');
			sb.append(value.charAt(i));
		}
		
		return sb.toString();
	}
}

Extends EntityProperty

If a subclass of EntityProperty is defined, it can convert property value for update by overriding convert(Object) method.

public MyEntityProperty<T extends PersistenceEntity> extends EntityProperty<T> {
	@Override
	protected Object convert(Object value) throws InvalidValueException, SystemException {
		...
	}

	// convert to string
	@Override
	protected Object getValueInternal(T entity, boolean convertToString) throws SystemException {
		...
	}
}
The value to convert can be a String or other type depending on its UI view component.

see Extensions on how to create custom EntityProperty types and render styles for custom UI components.

File UploadValidationFrames / No Frames