/*******************************************************************************
 * Copyright 2019 2Fi Business Solutions Ltd.
 *
 * This code is part of the Core project.
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.core.utils;

import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.bind.WebDataBinder;

import com.ffii.core.support.SimpleDateEditor;
import com.ffii.core.support.SimpleIntegerEditor;
import com.ffii.core.support.SimpleStringTrimToNullEditor;

/**
 * DataBindUtils
 *
 * @author Patrick
 */
public abstract class DataBindUtils {
	/** coreFields */
	public static final String[] coreFields = { Params.ID, "ownerId", "deleted", "createdBy", "modifiedBy", "created", "modified", "password" };

	/**
	 * 
	 * @param object
	 * @return WebDataBinder
	 */
	private static WebDataBinder createBinder(Object object) {
		WebDataBinder binder = new WebDataBinder(object);
		binder.registerCustomEditor(String.class, new SimpleStringTrimToNullEditor());
		binder.registerCustomEditor(Integer.class, new SimpleIntegerEditor());
		binder.registerCustomEditor(java.util.Date.class, new SimpleDateEditor());
		return binder;
	}

	/**
	 * Binds data using {@link WebDataBinder} with the following custom editors:-
	 *
	 * <ul>
	 * <li>{@link SimpleStringTrimToNullEditor}</li>
	 * <li>{@link SimpleIntegerEditor}</li>
	 * <li>{@link SimpleDateEditor}</li>
	 * </ul>
	 * 
	 * @param record
	 *            record Map
	 * @param object
	 *            the target object to bind onto
	 * @param disallowFields
	 *            optional
	 */
	public static void bindRecord(Map<String, Object> record, Object object, String... disallowFields) {
		WebDataBinder binder = createBinder(object);
		binder.setDisallowedFields(disallowFields);
		binder.bind(new MutablePropertyValues(record));
	};

	/**
	 * Binds data using {@link WebDataBinder} with the following custom editors:-
	 *
	 * <ul>
	 * <li>{@link SimpleStringTrimToNullEditor}</li>
	 * <li>{@link SimpleIntegerEditor}</li>
	 * <li>{@link SimpleDateEditor}</li>
	 * </ul>
	 * 
	 * <p>
	 * <b>Important:</b> The following system fields will NOT be binded for security reasons.
	 * <ul>
	 * <li>id</li>
	 * <li>ownerId</li>
	 * <li>deleted</li>
	 * <li>createdBy</li>
	 * <li>modifiedBy</li>
	 * <li>created</li>
	 * <li>modified</li>
	 * <li>password</li>
	 * </ul>
	 * </p>
	 * 
	 * @param record
	 *            record Map
	 * @param object
	 *            the target object to bind onto
	 * @param disallowFields
	 *            optional
	 */
	public static void bindRecordWithoutCore(Map<String, Object> record, Object object, String... disallowFields) {
		WebDataBinder binder = createBinder(object);

		binder.setDisallowedFields(ArrayUtils.addAll(coreFields, disallowFields));
		binder.bind(new MutablePropertyValues(record));
	};
}
