All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertigo.ui.core.MapUiObject Maven / Gradle / Ivy

There is a newer version: 4.2.0
Show newest version
/**
 * vertigo - simple java starter
 *
 * Copyright (C) 2013-2019, vertigo-io, KleeGroup, [email protected] (http://www.kleegroup.com)
 * KleeGroup, Centre d'affaire la Boursidiere - BP 159 - 92357 Le Plessis Robinson Cedex - France
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.vertigo.ui.core;

import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import io.vertigo.dynamo.domain.metamodel.DataType;
import io.vertigo.dynamo.domain.metamodel.Domain;
import io.vertigo.dynamo.domain.metamodel.DtField;
import io.vertigo.dynamo.domain.metamodel.FormatterException;
import io.vertigo.dynamo.domain.model.DtObject;
import io.vertigo.dynamo.domain.util.DtObjectUtil;
import io.vertigo.lang.Assertion;
import io.vertigo.ui.core.encoders.EncoderDate;
import io.vertigo.vega.engines.webservice.json.VegaUiObject;

/**
 * Objet d'IHM, fournit les valeurs formatés des champs de l'objet métier sous-jacent.
 * Implements Map car struts poste des String[] que l'on reconverti en String (on prend le premier).
 *
 * @author pchretien, npiedeloup
 * @param  Type de DtObject représenté par cet Input
 */
public final class MapUiObject extends VegaUiObject implements Map {
	private static final long serialVersionUID = -4639050257543017072L;
	private static final String DOMAIN_MULTIPLE_IDS = "DoMultipleIds";

	/**
	 * Constructor.
	 * @param serverSideDto DtObject
	 */
	public MapUiObject(final D serverSideDto) {
		this(serverSideDto, (D) DtObjectUtil.createDtObject(DtObjectUtil.findDtDefinition(serverSideDto)), Collections.emptySet());
	}

	/**
	 * Constructor.
	 * @param serverSideDto  DtObject
	 * @param inputDto Input DtObject
	 * @param modifiedFields List of modified fields
	 */
	public MapUiObject(final D serverSideDto, final D inputDto, final Set modifiedFields) {
		super(inputDto, modifiedFields);
		setServerSideObject(serverSideDto);
	}

	/** {@inheritDoc} */
	@Override
	public Serializable get(final Object key) {
		final String keyFieldName = String.class.cast(key);
		Assertion.checkArgNotEmpty(keyFieldName);
		Assertion.checkArgument(Character.isLowerCase(keyFieldName.charAt(0)) && !keyFieldName.contains("_"), "Le nom du champs doit-être en camelCase ({0}).", keyFieldName);
		//-----
		final DtField dtField = getDtField(keyFieldName);
		if (isMultiple(dtField)) {
			final String strValue = getInputValue(keyFieldName);
			return parseMultipleValue(strValue);
		} else if (isBoolean(dtField)) {
			final Boolean value = getTypedValue(keyFieldName, Boolean.class);
			return value != null ? String.valueOf(value) : null;
		} else {
			return getInputValue(keyFieldName);
		}
	}

	/** {@inheritDoc} */
	@Override
	public String put(final String fieldName, final Serializable value) {
		Assertion.checkArgNotEmpty(fieldName);
		Assertion.checkNotNull(value, "La valeur formatée ne doit pas être null mais vide ({0})", fieldName);
		Assertion.checkState(value instanceof String || value instanceof String[], "Les données saisies doivent être de type String ou String[] ({0} : {1})", fieldName, value.getClass());
		//-----
		final DtField dtField = getDtField(fieldName);
		String strValue;
		if (isMultiple(dtField)) {
			strValue = formatMultipleValue(value);
		} else if (isAboutDate(dtField)) {
			strValue = requestParameterToString(value);
			try {
				final Object typedValue = EncoderDate.stringToValue(strValue, dtField.getDomain().getDataType());
				strValue = dtField.getDomain().valueToString(typedValue);// we fall back in the normal case if everything is right -> go to formatter
			} catch (final FormatterException e) {
				// do nothing we keep the input value
			}
		} else {
			strValue = requestParameterToString(value);
		}
		setInputValue(fieldName, strValue);
		return null;
	}

	private static String requestParameterToString(final Serializable value) {
		return value instanceof String[] ? ((String[]) value)[0] : (String) value;
	}

	private static String formatMultipleValue(final Object values) {
		if (values instanceof String) {
			// just one
			return (String) values;
		}
		// we are a String array
		return Arrays
				.stream((String[]) values)
				.collect(Collectors.joining(";"));
	}

	private static String[] parseMultipleValue(final String strValue) {
		return strValue.split(";");
	}

	private static boolean isMultiple(final DtField dtField) {
		return DOMAIN_MULTIPLE_IDS.equals(dtField.getDomain().getName());
	}

	private static boolean isBoolean(final DtField dtField) {
		return dtField.getDomain().getDataType() == DataType.Boolean;
	}

	private static boolean isAboutDate(final DtField dtField) {
		return dtField.getDomain().getDataType().isAboutDate();
	}

	/** {@inheritDoc} */
	@Override
	public boolean containsKey(final Object arg0) {
		return fieldIndex.contains(arg0);
	}

	/** Non implémenté. */
	@Override
	public void clear() {
		throw new UnsupportedOperationException();
	}

	/** Non implémenté. */
	@Override
	public boolean containsValue(final Object arg0) {
		throw new UnsupportedOperationException();
	}

	/** Implémentation : TODO : see if it's ok */
	@Override
	public Set> entrySet() {
		return fieldIndex
				.stream()
				.map(key -> new AbstractMap.SimpleEntry<>(key, get(key)))
				.collect(Collectors.toSet());
	}

	/** {@inheritDoc} */
	@Override
	public boolean isEmpty() {
		return fieldIndex.isEmpty();
	}

	/** {@inheritDoc} */
	@Override
	public Set keySet() {
		return fieldIndex;
	}

	/** Not supported. */
	@Override
	public void putAll(final Map arg0) {
		throw new UnsupportedOperationException();
	}

	/** Not supported. */
	@Override
	public String remove(final Object arg0) {
		throw new UnsupportedOperationException();
	}

	/** {@inheritDoc} */
	@Override
	public int size() {
		return fieldIndex.size();
	}

	/** Not supported. */
	@Override
	public Collection values() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Return the typed value.
	 * @param fieldName Field
	 * @return Typed value
	 */
	public Serializable getTypedValue(final String fieldName) {
		return getTypedValue(fieldName, Serializable.class);
	}

	/**
	 * Return a Serializable Map for client.
	 * @param fieldsForClient List of fields
	 * @param valueTransformers Map of transformers
	 * @return HashMap (needed for Serializable)
	 */
	public HashMap mapForClient(final Set fieldsForClient, final Map> valueTransformers) {
		final Set filterSet;
		if (fieldsForClient.contains("*")) {
			filterSet = fieldIndex;
		} else {
			filterSet = fieldsForClient;
		}
		final HashMap mapForClient = new HashMap<>(filterSet.size());
		filterSet
				.forEach(key -> mapForClient.put(key, getValueForClient(key, valueTransformers.get(key))));
		return mapForClient;

	}

	private Serializable getValueForClient(final String fieldKey, final Function valueTransformer) {
		final boolean hasFormatModifier = fieldKey.endsWith("_fmt");
		final boolean hasDisplayModifier = fieldKey.endsWith("_display");
		final String fieldName;
		if (hasFormatModifier) {
			fieldName = fieldKey.substring(0, fieldKey.length() - "_fmt".length());
		} else {
			fieldName = hasDisplayModifier ? fieldKey.substring(0, fieldKey.length() - "_display".length()) : fieldKey;
		}
		//--- if error
		if (hasFormatError(fieldName)) {
			return getInputValue(fieldName);
		}
		//--- good data
		if (hasFormatModifier) {
			return getFormattedValue(fieldName);
		}
		if (valueTransformer != null) {
			return valueTransformer.apply(getTypedValue(fieldName, Serializable.class));
		}
		return getEncodedValue(fieldName);

	}

	private Serializable getEncodedValue(final String key) {
		final String keyFieldName = String.class.cast(key);
		Assertion.checkArgNotEmpty(keyFieldName);
		Assertion.checkArgument(Character.isLowerCase(keyFieldName.charAt(0)) && !keyFieldName.contains("_"), "Le nom du champs doit-être en camelCase ({0}).", keyFieldName);
		//---
		final DtField dtField = getDtField(keyFieldName);
		if (isAboutDate(dtField)) {
			final Serializable value = getTypedValue(keyFieldName, Serializable.class);
			final Domain domain = dtField.getDomain();
			return EncoderDate.valueToString(value, domain.getDataType());// encodeValue
		} else if (isMultiple(dtField)) {
			final String value = getTypedValue(keyFieldName, String.class);
			return value != null ? parseMultipleValue(value) : new String[0];
		}
		return getTypedValue(keyFieldName, Serializable.class);
	}

	private String getFormattedValue(final String keyFieldName) {

		final DtField dtField = getDtField(keyFieldName);
		final Serializable typedValue = getEncodedValue(keyFieldName);
		return typedValue != null ? dtField.getDomain().valueToString(typedValue) : null;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy