<commit_before>package org.lightadmin.core.rest;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType;
import org.lightadmin.core.config.domain.DomainTypeAdministrationConfiguration;
import org.lightadmin.core.config.domain.DomainTypeBasicConfiguration;
import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration;
import org.lightadmin.core.config.domain.configuration.support.EntityNameExtractor;
import org.lightadmin.core.config.domain.field.FieldMetadata;
import org.lightadmin.core.config.domain.field.FieldMetadataUtils;
import org.lightadmin.core.config.domain.field.Persistable;
import org.lightadmin.core.config.domain.field.PersistentFieldMetadata;
import org.lightadmin.core.config.domain.field.evaluator.FieldValueEvaluator;
import org.lightadmin.core.persistence.metamodel.DomainTypeAttributeType;
import org.lightadmin.core.persistence.metamodel.DomainTypeEntityMetadata;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.rest.webmvc.EntityResource;
import org.springframework.data.rest.webmvc.RepositoryRestConfiguration;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.Maps.newLinkedHashMap;
import static java.util.Collections.EMPTY_SET;
import static org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType.LIST_VIEW;
import static org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType.QUICK_VIEW;
import static org.lightadmin.core.config.domain.configuration.support.ExceptionAwareTransformer.exceptionAwareNameExtractor;
import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.addPrimaryKeyPersistentField;

@SuppressWarnings("unchecked")
public class DomainTypeToResourceConverter extends DomainTypeResourceSupport implements Converter<Object, Resource> {

	private final FieldValueEvaluator fieldValueEvaluator = new FieldValueEvaluator();

	private GlobalAdministrationConfiguration configuration;

	public DomainTypeToResourceConverter( GlobalAdministrationConfiguration configuration, RepositoryRestConfiguration restConfiguration ) {
		super( restConfiguration );
		this.configuration = configuration;
	}

	public Resource convert( final Object source, DomainConfigurationUnitType configurationUnitType, Set<FieldMetadata> fieldMetadatas ) {
		if ( source == null ) {
			return null;
		}

		final DomainTypeBasicConfiguration domainTypeConfiguration = configuration.forDomainType( source.getClass() );
		if ( domainTypeConfiguration == null ) {
			return new Resource<Object>( source );
		}

		final DomainTypeEntityMetadata entityMetadata = domainTypeConfiguration.getDomainTypeEntityMetadata();

		Serializable id = ( Serializable ) entityMetadata.getIdAttribute().getValue( source );

		final EntityResource entityResource = newEntityResource( domainTypeConfiguration.getDomainTypeName(), id );

		addObjectStringRepresentation( entityResource, domainTypeConfiguration, source );

		addManagedTypeProperty( entityResource, source );

		for ( FieldMetadata field : fieldMetadatas ) {
			addFieldAttributeValue( entityResource, source, id, field, domainTypeConfiguration, configurationUnitType );
		}

		return entityResource;
	}

	@Override
	public Resource convert( Object source ) {
		if ( source == null ) {
			return null;
		}

		final DomainTypeAdministrationConfiguration domainTypeConfiguration = configuration.forManagedDomainType( source.getClass() );
		final DomainTypeBasicConfiguration domainTypeBasicConfig = configuration.forDomainType( source.getClass() );

		if ( domainTypeConfiguration != null ) {
			return convert( source, QUICK_VIEW, primaryKeyFieldOnly( domainTypeConfiguration ) );
		}

		if ( domainTypeBasicConfig != null ) {
			return convert( source, QUICK_VIEW, primaryKeyFieldOnly( domainTypeBasicConfig ) );
		}

		return new Resource<Object>( source );
	}

	private Set<FieldMetadata> primaryKeyFieldOnly( DomainTypeBasicConfiguration domainTypeBasicConfig ) {
		return addPrimaryKeyPersistentField( EMPTY_SET, domainTypeBasicConfig.getDomainTypeEntityMetadata().getIdAttribute() );
	}

	private void addObjectStringRepresentation( final EntityResource resource, final DomainTypeBasicConfiguration configuration, final Object source ) {
		final EntityNameExtractor nameExtractor = configuration.getEntityConfiguration().getNameExtractor();

		resource.getContent().put( "stringRepresentation", exceptionAwareNameExtractor( nameExtractor ).apply( source ) );
	}

	private Object addManagedTypeProperty( final EntityResource entityResource, final Object source ) {
		return entityResource.getContent().put( "managedDomainType", configuration.forManagedDomainType( source.getClass() ) != null );
	}

	private void addFieldAttributeValue( EntityResource resource, Object source, final Serializable id, FieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, DomainConfigurationUnitType configurationUnitType ) {
		if ( FieldMetadataUtils.persistentFieldMetadataPredicate().apply( field ) ) {
			addAttributeValue( resource, field.getUuid(), persistentFieldData( source, id, ( PersistentFieldMetadata ) field, domainTypeConfiguration, configurationUnitType ) );
		} else {
			addAttributeValue( resource, field.getUuid(), transientFieldData( field, source ) );
		}
	}

	private Map<String, Object> transientFieldData( FieldMetadata field, Object source ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		final Object fieldValue = fieldValueEvaluator.evaluate( field, source );
		final DomainTypeAttributeType type = fieldValue != null ? DomainTypeAttributeType.forType( fieldValue.getClass() ) : DomainTypeAttributeType.UNKNOWN;

		fieldData.put( "name", field.getName() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "value", fieldValue );
		fieldData.put( "type", type.name() );
		fieldData.put( "persistable", false );

		return fieldData;
	}

	private Map<String, Object> persistentFieldData( final Object source, final Serializable id, final PersistentFieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, final DomainConfigurationUnitType configurationUnitType ) {
		if ( field.getAttributeMetadata().getAttributeType() == DomainTypeAttributeType.FILE ) {
			return persistentFileFieldData( source, id, field, domainTypeConfiguration, configurationUnitType );
		}

		return persistentSimpleFieldData( field, source );
	}

	private Map<String, Object> persistentSimpleFieldData( PersistentFieldMetadata field, Object source ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		fieldData.put( "name", field.getField() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "value", fieldValueEvaluator.evaluate( field, source ) );
		fieldData.put( "type", field.getAttributeMetadata().getAttributeType().name() );
		fieldData.put( "persistable", true );
		fieldData.put( "primaryKey", field.isPrimaryKey() );

		return fieldData;
	}

	private Map<String, Object> persistentFileFieldData( Object source, final Serializable id, PersistentFieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, final DomainConfigurationUnitType configurationUnitType ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		final byte[] fileContent = ( byte[] ) fieldValueEvaluator.evaluate( field, source );

		fieldData.put( "name", field.getField() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "type", DomainTypeAttributeType.FILE.name() );
		if ( configurationUnitType != LIST_VIEW ) {
			fieldData.put( "value", fieldValueEvaluator.evaluate( field, source ) );
		}
		fieldData.put( "persistable", true );
		fieldData.put( "fileExists", fileContent != null && fileContent.length > 0 );
		fieldData.put( "fileUrl", filePropertyLink( field, domainTypeConfiguration.getDomainTypeName(), id ) );

		return fieldData;
	}

	private String filePropertyLink( final Persistable persistable, final String domainTypeName, final Serializable id ) {
		return UriComponentsBuilder.fromUri( restConfiguration.getBaseUri() ).pathSegment( domainTypeName ).pathSegment( id.toString() ).pathSegment( persistable.getField() ).pathSegment( "file" ).build().toUri().toString();
	}<commit_msg>#70 Image fields support: Performance optimization on ListView<commit_after>package org.lightadmin.core.rest;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType;
import org.lightadmin.core.config.domain.DomainTypeAdministrationConfiguration;
import org.lightadmin.core.config.domain.DomainTypeBasicConfiguration;
import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration;
import org.lightadmin.core.config.domain.configuration.support.EntityNameExtractor;
import org.lightadmin.core.config.domain.field.FieldMetadata;
import org.lightadmin.core.config.domain.field.FieldMetadataUtils;
import org.lightadmin.core.config.domain.field.Persistable;
import org.lightadmin.core.config.domain.field.PersistentFieldMetadata;
import org.lightadmin.core.config.domain.field.evaluator.FieldValueEvaluator;
import org.lightadmin.core.persistence.metamodel.DomainTypeAttributeType;
import org.lightadmin.core.persistence.metamodel.DomainTypeEntityMetadata;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.rest.webmvc.EntityResource;
import org.springframework.data.rest.webmvc.RepositoryRestConfiguration;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.Maps.newLinkedHashMap;
import static java.util.Collections.EMPTY_SET;
import static org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType.FORM_VIEW;
import static org.lightadmin.core.config.bootstrap.parsing.configuration.DomainConfigurationUnitType.QUICK_VIEW;
import static org.lightadmin.core.config.domain.configuration.support.ExceptionAwareTransformer.exceptionAwareNameExtractor;
import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.addPrimaryKeyPersistentField;

@SuppressWarnings("unchecked")
public class DomainTypeToResourceConverter extends DomainTypeResourceSupport implements Converter<Object, Resource> {

	private final FieldValueEvaluator fieldValueEvaluator = new FieldValueEvaluator();

	private GlobalAdministrationConfiguration configuration;

	public DomainTypeToResourceConverter( GlobalAdministrationConfiguration configuration, RepositoryRestConfiguration restConfiguration ) {
		super( restConfiguration );
		this.configuration = configuration;
	}

	public Resource convert( final Object source, DomainConfigurationUnitType configurationUnitType, Set<FieldMetadata> fieldMetadatas ) {
		if ( source == null ) {
			return null;
		}

		final DomainTypeBasicConfiguration domainTypeConfiguration = configuration.forDomainType( source.getClass() );
		if ( domainTypeConfiguration == null ) {
			return new Resource<Object>( source );
		}

		final DomainTypeEntityMetadata entityMetadata = domainTypeConfiguration.getDomainTypeEntityMetadata();

		Serializable id = ( Serializable ) entityMetadata.getIdAttribute().getValue( source );

		final EntityResource entityResource = newEntityResource( domainTypeConfiguration.getDomainTypeName(), id );

		addObjectStringRepresentation( entityResource, domainTypeConfiguration, source );

		addManagedTypeProperty( entityResource, source );

		for ( FieldMetadata field : fieldMetadatas ) {
			addFieldAttributeValue( entityResource, source, id, field, domainTypeConfiguration, configurationUnitType );
		}

		return entityResource;
	}

	@Override
	public Resource convert( Object source ) {
		if ( source == null ) {
			return null;
		}

		final DomainTypeAdministrationConfiguration domainTypeConfiguration = configuration.forManagedDomainType( source.getClass() );
		final DomainTypeBasicConfiguration domainTypeBasicConfig = configuration.forDomainType( source.getClass() );

		if ( domainTypeConfiguration != null ) {
			return convert( source, QUICK_VIEW, primaryKeyFieldOnly( domainTypeConfiguration ) );
		}

		if ( domainTypeBasicConfig != null ) {
			return convert( source, QUICK_VIEW, primaryKeyFieldOnly( domainTypeBasicConfig ) );
		}

		return new Resource<Object>( source );
	}

	private Set<FieldMetadata> primaryKeyFieldOnly( DomainTypeBasicConfiguration domainTypeBasicConfig ) {
		return addPrimaryKeyPersistentField( EMPTY_SET, domainTypeBasicConfig.getDomainTypeEntityMetadata().getIdAttribute() );
	}

	private void addObjectStringRepresentation( final EntityResource resource, final DomainTypeBasicConfiguration configuration, final Object source ) {
		final EntityNameExtractor nameExtractor = configuration.getEntityConfiguration().getNameExtractor();

		resource.getContent().put( "stringRepresentation", exceptionAwareNameExtractor( nameExtractor ).apply( source ) );
	}

	private Object addManagedTypeProperty( final EntityResource entityResource, final Object source ) {
		return entityResource.getContent().put( "managedDomainType", configuration.forManagedDomainType( source.getClass() ) != null );
	}

	private void addFieldAttributeValue( EntityResource resource, Object source, final Serializable id, FieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, DomainConfigurationUnitType configurationUnitType ) {
		if ( FieldMetadataUtils.persistentFieldMetadataPredicate().apply( field ) ) {
			addAttributeValue( resource, field.getUuid(), persistentFieldData( source, id, ( PersistentFieldMetadata ) field, domainTypeConfiguration, configurationUnitType ) );
		} else {
			addAttributeValue( resource, field.getUuid(), transientFieldData( field, source ) );
		}
	}

	private Map<String, Object> transientFieldData( FieldMetadata field, Object source ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		final Object fieldValue = fieldValueEvaluator.evaluate( field, source );
		final DomainTypeAttributeType type = fieldValue != null ? DomainTypeAttributeType.forType( fieldValue.getClass() ) : DomainTypeAttributeType.UNKNOWN;

		fieldData.put( "name", field.getName() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "value", fieldValue );
		fieldData.put( "type", type.name() );
		fieldData.put( "persistable", false );

		return fieldData;
	}

	private Map<String, Object> persistentFieldData( final Object source, final Serializable id, final PersistentFieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, final DomainConfigurationUnitType configurationUnitType ) {
		if ( field.getAttributeMetadata().getAttributeType() == DomainTypeAttributeType.FILE ) {
			return persistentFileFieldData( source, id, field, domainTypeConfiguration, configurationUnitType );
		}

		return persistentSimpleFieldData( field, source );
	}

	private Map<String, Object> persistentSimpleFieldData( PersistentFieldMetadata field, Object source ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		fieldData.put( "name", field.getField() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "value", fieldValueEvaluator.evaluate( field, source ) );
		fieldData.put( "type", field.getAttributeMetadata().getAttributeType().name() );
		fieldData.put( "persistable", true );
		fieldData.put( "primaryKey", field.isPrimaryKey() );

		return fieldData;
	}

	private Map<String, Object> persistentFileFieldData( Object source, final Serializable id, PersistentFieldMetadata field, final DomainTypeBasicConfiguration domainTypeConfiguration, final DomainConfigurationUnitType configurationUnitType ) {
		final Map<String, Object> fieldData = newLinkedHashMap();

		final byte[] fileContent = ( byte[] ) fieldValueEvaluator.evaluate( field, source );

		fieldData.put( "name", field.getField() );
		fieldData.put( "title", field.getName() );
		fieldData.put( "type", DomainTypeAttributeType.FILE.name() );
		if ( configurationUnitType == FORM_VIEW ) {
			fieldData.put( "value", fieldValueEvaluator.evaluate( field, source ) );
		}
		fieldData.put( "persistable", true );
		fieldData.put( "fileExists", fileContent != null && fileContent.length > 0 );
		fieldData.put( "fileUrl", filePropertyLink( field, domainTypeConfiguration.getDomainTypeName(), id ) );

		return fieldData;
	}

	private String filePropertyLink( final Persistable persistable, final String domainTypeName, final Serializable id ) {
		return UriComponentsBuilder.fromUri( restConfiguration.getBaseUri() ).pathSegment( domainTypeName ).pathSegment( id.toString() ).pathSegment( persistable.getField() ).pathSegment( "file" ).build().toUri().toString();
	}
{'fraction_non_alphanumeric': 0.09500552357695215, 'fraction_numerical': 0.0002325716611430897, 'mean_word_length': 6.7898550724637685, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5221722', 'n_tokens_mistral': 4664, 'n_tokens_neox': 4383, 'n_words': 973}