<commit_before>/*
 * This file is part of Geomajas, a component framework for building
 * rich Internet applications (RIA) with sophisticated capabilities for the
 * display, analysis and management of geographic information.
 * It is a building block that allows developers to add maps
 * and other geographic data capabilities to their web applications.
 *
 * Copyright 2008-2010 Geosparc, http://www.geosparc.com, Belgium
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.geomajas.internal.filter;

import org.geomajas.internal.layer.feature.FeatureModelRegistry;
import org.geomajas.layer.LayerException;
import org.geomajas.layer.feature.FeatureModel;
import org.geotools.factory.Hints;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.filter.expression.PropertyAccessor;
import org.geotools.filter.expression.PropertyAccessorFactory;

import java.util.regex.Pattern;

/**
 * <p>
 * Implementation of the normal geotools PropertyAccessorFactory factory. Geotools can only handle the retrieval of
 * simple attributes, and is therefore not strong enough for the possibilities that Hibernate Spatial gives us. That is
 * where this class comes in. It uses the FeatureModel's of the features to retrieve the correct attributes. This way,
 * we can search for complex attributes in complex objects, still using the default geotools Filter.evaluate(Object)
 * function calls.
 * </p>
 * 
 * @author <NAME>
 */
public class FeatureModelPropertyAccessorFactory implements PropertyAccessorFactory {

	private static final PropertyAccessor ACCESSOR = new FeatureModelPropertyAccessor();

	public PropertyAccessor createPropertyAccessor(Class type, String xpath, Class target, Hints hints) {
		return ACCESSOR;
	}

	/**
	 * Property accessor for feature models
	 */
	static class FeatureModelPropertyAccessor implements PropertyAccessor {

		private static Pattern ID_PATTERN = Pattern.compile("@(\\w+:)?id");

		private static Pattern PROPERTY_PATTERN = Pattern.compile("(\\w+:)?(\\w+)");

		public boolean canHandle(Object object, String xpath, Class target) {
			FeatureModel fm = FeatureModelRegistry.getRegistry().lookup(object);
			return (fm != null);
		}

		public Object get(Object object, String xpath, Class target) throws IllegalArgumentException {
			FeatureModel fm = FeatureModelRegistry.getRegistry().lookup(object);
			if (null == fm) {
				throw new IllegalArgumentException("Objects of type " + object.getClass().getName() +
						" not registered in FeatureModelRegistry");
			}
			try {
				if (xpath.equals(fm.getGeometryAttributeName())) {
					return fm.getGeometry(object);
				} else if (ID_PATTERN.matcher(xpath).matches()) {
					return fm.getId(object);
				} else if (PROPERTY_PATTERN.matcher(xpath).matches()) {
					return fm.getAttribute(object, xpath).getValue();
				} else {
					return null;
				}
			} catch (LayerException e) {
				throw new IllegalArgumentException(e);
			}
		}

		public void set(Object object, String xpath, Object value, Class target) throws IllegalAttributeException,
				IllegalArgumentException {
			throw new IllegalAttributeException("feature is immutable, only use property access for filtering");
		}
	}

}<commit_msg>MAJ-953 do not use deprecated IllegalAttributeException<commit_after>/*
 * This file is part of Geomajas, a component framework for building
 * rich Internet applications (RIA) with sophisticated capabilities for the
 * display, analysis and management of geographic information.
 * It is a building block that allows developers to add maps
 * and other geographic data capabilities to their web applications.
 *
 * Copyright 2008-2010 Geosparc, http://www.geosparc.com, Belgium
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.geomajas.internal.filter;

import org.geomajas.internal.layer.feature.FeatureModelRegistry;
import org.geomajas.layer.LayerException;
import org.geomajas.layer.feature.FeatureModel;
import org.geotools.factory.Hints;
import org.geotools.filter.expression.PropertyAccessor;
import org.geotools.filter.expression.PropertyAccessorFactory;

import java.util.regex.Pattern;

/**
 * <p>
 * Implementation of the normal GeoTools PropertyAccessorFactory factory. GeoTools can only handle the retrieval of
 * simple attributes, and is therefore not strong enough for the possibilities that Hibernate Spatial gives us. That is
 * where this class comes in. It uses the FeatureModel's of the features to retrieve the correct attributes. This way,
 * we can search for complex attributes in complex objects, still using GeoTools' default Filter.evaluate(Object)
 * function calls.
 * </p>
 * 
 * @author <NAME>
 */
public class FeatureModelPropertyAccessorFactory implements PropertyAccessorFactory {

	private static final PropertyAccessor ACCESSOR = new FeatureModelPropertyAccessor();

	public PropertyAccessor createPropertyAccessor(Class type, String xpath, Class target, Hints hints) {
		return ACCESSOR;
	}

	/**
	 * Property accessor for feature models
	 */
	static class FeatureModelPropertyAccessor implements PropertyAccessor {

		private static Pattern ID_PATTERN = Pattern.compile("@(\\w+:)?id");

		private static Pattern PROPERTY_PATTERN = Pattern.compile("(\\w+:)?(\\w+)");

		public boolean canHandle(Object object, String xpath, Class target) {
			FeatureModel fm = FeatureModelRegistry.getRegistry().lookup(object);
			return (fm != null);
		}

		public Object get(Object object, String xpath, Class target) throws IllegalArgumentException {
			FeatureModel fm = FeatureModelRegistry.getRegistry().lookup(object);
			if (null == fm) {
				throw new IllegalArgumentException("Objects of type " + object.getClass().getName() +
						" not registered in FeatureModelRegistry");
			}
			try {
				if (xpath.equals(fm.getGeometryAttributeName())) {
					return fm.getGeometry(object);
				} else if (ID_PATTERN.matcher(xpath).matches()) {
					return fm.getId(object);
				} else if (PROPERTY_PATTERN.matcher(xpath).matches()) {
					return fm.getAttribute(object, xpath).getValue();
				} else {
					return null;
				}
			} catch (LayerException e) {
				throw new IllegalArgumentException(e);
			}
		}

		public void set(Object object, String xpath, Object value, Class target) throws IllegalArgumentException {
			throw new IllegalArgumentException("feature is immutable, only use property access for filtering");
		}
	}

}
{'fraction_non_alphanumeric': 0.08165090723230257, 'fraction_numerical': 0.0026833631484794273, 'mean_word_length': 3.9600760456273765, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '4447227', 'n_tokens_mistral': 2229, 'n_tokens_neox': 1944, 'n_words': 757}