<commit_before>package com.nhl.link.move.runtime.path;

import com.nhl.link.move.LmRuntimeException;
import com.nhl.link.move.runtime.LmRuntimeBuilder;
import com.nhl.link.move.runtime.jdbc.JdbcNormalizer;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.exp.parser.ASTDbPath;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.PathComponent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @since 1.4
 */
public class PathNormalizer implements IPathNormalizer {

	private ConcurrentMap<String, EntityPathNormalizer> pathCache;
	private Map<String, JdbcNormalizer> jdbcNormalizers;

	public PathNormalizer(@Inject(LmRuntimeBuilder.JDBC_NORMALIZERS_MAP) Map<String, JdbcNormalizer> jdbcNormalizers) {
		pathCache = new ConcurrentHashMap<>();
		this.jdbcNormalizers = jdbcNormalizers;
	}

	@Override
	public EntityPathNormalizer normalizer(ObjEntity root) {

		if (root == null) {
			throw new NullPointerException("Null root entity");
		}

		EntityPathNormalizer normalizer = pathCache.get(root.getName());

		if (normalizer == null) {
			EntityPathNormalizer newNormalizer = createNormalizer(root);
			EntityPathNormalizer oldNormalizer = pathCache.putIfAbsent(root.getName(), newNormalizer);
			normalizer = oldNormalizer != null ? oldNormalizer : newNormalizer;
		}

		return normalizer;
	}

	private EntityPathNormalizer createNormalizer(final ObjEntity entity) {

		return new EntityPathNormalizer() {

			ConcurrentMap<String, AttributeInfo> cachedAttributes = new ConcurrentHashMap<>();

			@Override
			public String normalize(String path) {

				if (!entity.getAttributeMap().containsKey(path) && !entity.getRelationshipMap().containsKey(path)) {
					return path;
				}

				if (path == null) {
					throw new NullPointerException("Null path. Entity: " + entity.getName());
				}

				return getAttributeInfo(path).getNormalizedPath();
			}

			@Override
			public Object normalizeValue(String path, Object value) {

				if (value == null) {
					return null;
				}

				AttributeInfo attributeInfo =  getAttributeInfo(path);

				JdbcNormalizer normalizer = jdbcNormalizers.get(Integer.valueOf(attributeInfo.getType()).toString());
				if (normalizer == null) {
					return value;
				} else {
					return normalizer.normalize(value);
				}
			}

			private AttributeInfo getAttributeInfo(String path) {

				AttributeInfo normalizedInfo = cachedAttributes.get(path);
				if (normalizedInfo == null) {
					AttributeInfo newNormalizedInfo = doNormalize(path);
					AttributeInfo oldNormalizedInfo = cachedAttributes.putIfAbsent(path, newNormalizedInfo);
					normalizedInfo = oldNormalizedInfo != null ? oldNormalizedInfo : newNormalizedInfo;
				}

				return normalizedInfo;
			}

			private AttributeInfo doNormalize(String path) {

				Expression dbExp = entity.translateToDbPath(ExpressionFactory.exp(path));

				List<PathComponent<DbAttribute, DbRelationship>> components = new ArrayList<>(2);
				for (PathComponent<DbAttribute, DbRelationship> c : entity.getDbEntity().resolvePath(dbExp,
						Collections.emptyMap())) {<commit_msg>#35 Long / Integer values in HashMap keys<commit_after>package com.nhl.link.move.runtime.path;

import com.nhl.link.move.LmRuntimeException;
import com.nhl.link.move.runtime.LmRuntimeBuilder;
import com.nhl.link.move.runtime.jdbc.JdbcNormalizer;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.exp.parser.ASTDbPath;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.PathComponent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @since 1.4
 */
public class PathNormalizer implements IPathNormalizer {

	private ConcurrentMap<String, EntityPathNormalizer> pathCache;
	private Map<String, JdbcNormalizer> jdbcNormalizers;

	public PathNormalizer(@Inject(LmRuntimeBuilder.JDBC_NORMALIZERS_MAP) Map<String, JdbcNormalizer> jdbcNormalizers) {
		pathCache = new ConcurrentHashMap<>();
		this.jdbcNormalizers = jdbcNormalizers;
	}

	@Override
	public EntityPathNormalizer normalizer(ObjEntity root) {

		if (root == null) {
			throw new NullPointerException("Null root entity");
		}

		EntityPathNormalizer normalizer = pathCache.get(root.getName());

		if (normalizer == null) {
			EntityPathNormalizer newNormalizer = createNormalizer(root);
			EntityPathNormalizer oldNormalizer = pathCache.putIfAbsent(root.getName(), newNormalizer);
			normalizer = oldNormalizer != null ? oldNormalizer : newNormalizer;
		}

		return normalizer;
	}

	private EntityPathNormalizer createNormalizer(final ObjEntity entity) {

		return new EntityPathNormalizer() {

			ConcurrentMap<String, AttributeInfo> cachedAttributes = new ConcurrentHashMap<>();

			@Override
			public String normalize(String path) {

				if (!hasAttribute(entity, path)) {
					return path;
				}

				if (path == null) {
					throw new NullPointerException("Null path. Entity: " + entity.getName());
				}

				return getAttributeInfo(path).getNormalizedPath();
			}

			@Override
			public Object normalizeValue(String path, Object value) {

				if (!hasAttribute(entity, path)) {
					return value;
				}

				if (value == null) {
					return null;
				}

				AttributeInfo attributeInfo =  getAttributeInfo(path);

				JdbcNormalizer normalizer = jdbcNormalizers.get(Integer.valueOf(attributeInfo.getType()).toString());
				if (normalizer == null) {
					return value;
				} else {
					return normalizer.normalize(value);
				}
			}

			private boolean hasAttribute(ObjEntity entity, String path) {
				if (path.startsWith(ASTDbPath.DB_PREFIX)) {
					path = path.replace(ASTDbPath.DB_PREFIX, "");
					return entity.getDbEntity().getAttributeMap().containsKey(path)
							|| entity.getDbEntity().getRelationshipMap().containsKey(path);
				} else {
					return entity.getAttributeMap().containsKey(path) || entity.getRelationshipMap().containsKey(path);
				}
			}

			private AttributeInfo getAttributeInfo(String path) {

				AttributeInfo normalizedInfo = cachedAttributes.get(path);
				if (normalizedInfo == null) {
					AttributeInfo newNormalizedInfo = doNormalize(path);
					AttributeInfo oldNormalizedInfo = cachedAttributes.putIfAbsent(path, newNormalizedInfo);
					normalizedInfo = oldNormalizedInfo != null ? oldNormalizedInfo : newNormalizedInfo;
				}

				return normalizedInfo;
			}

			private AttributeInfo doNormalize(String path) {

				Expression dbExp = entity.translateToDbPath(ExpressionFactory.exp(path));

				List<PathComponent<DbAttribute, DbRelationship>> components = new ArrayList<>(2);
				for (PathComponent<DbAttribute, DbRelationship> c : entity.getDbEntity().resolvePath(dbExp,
						Collections.emptyMap())) {
{'fraction_non_alphanumeric': 0.10535593220338983, 'fraction_numerical': 0.0010847457627118644, 'mean_word_length': 4.812450748620962, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, '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': '7320656', 'n_tokens_mistral': 2501, 'n_tokens_neox': 2151, 'n_words': 424}