<commit_before>/* Copyright 2004-2005 the original author or authors.
 *
 * 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 org.codehaus.groovy.grails.commons;

import grails.util.GrailsNameUtils;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.codehaus.groovy.grails.validation.ConstrainedProperty;
import org.codehaus.groovy.grails.validation.ConstraintsEvaluator;
import org.codehaus.groovy.grails.validation.DefaultConstraintEvaluator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

/**
 * Represents a property of a domain class and contains meta information about the
 * properties relationships, naming conventions and type.
 *
 * @author <NAME>
 * @since 0.1
 */
public class DefaultGrailsDomainClassProperty implements GrailsDomainClassProperty {

    private GrailsDomainClass domainClass;
    private boolean persistent = true; // persistant by default
    private boolean identity;
    private boolean oneToMany;
    private String name;
    private Class<?> type;
    private boolean manyToMany;
    private boolean manyToOne;
    private boolean oneToOne;
    private boolean hasOne = false;
    private boolean bidirectional;
    private boolean derived = false;

    private Class<?> referencedPropertyType;
    private GrailsDomainClass referencedDomainClass;
    private GrailsDomainClassProperty otherSide;
    private String naturalName;
    private boolean inherited;
    private int fetchMode = FETCH_LAZY;
    private boolean owningSide;
    private String referencePropertyName;
    private boolean embedded;
    private GrailsDomainClass component;
    private boolean basicCollectionType;
    private Map<String, Object> defaultConstraints;

    /**
     * Constructor.
     * @param domainClass
     * @param descriptor
     */
    @SuppressWarnings("rawtypes")
    public DefaultGrailsDomainClassProperty(GrailsDomainClass domainClass, PropertyDescriptor descriptor) {
        this(domainClass, descriptor, null);
    }

    /**
     * Constructor.
     * @param domainClass
     * @param descriptor
     */
    @SuppressWarnings("rawtypes")
    public DefaultGrailsDomainClassProperty(GrailsDomainClass domainClass, PropertyDescriptor descriptor, Map<String, Object> defaultConstraints) {
        this.domainClass = domainClass;
        name = descriptor.getName();
        naturalName = GrailsNameUtils.getNaturalName(descriptor.getName());
        type = descriptor.getPropertyType();
        identity = descriptor.getName().equals(IDENTITY);

        // establish if property is persistant
        if (domainClass != null) {
            // figure out if this property is inherited
            if (!domainClass.isRoot()) {
                inherited = GrailsClassUtils.isPropertyInherited(domainClass.getClazz(), name);
            }
            List transientProps = getTransients();
            checkIfTransient(transientProps);

            establishFetchMode();
        }

        if (descriptor.getReadMethod() == null || descriptor.getWriteMethod() == null) {
            persistent = false;
        }

        if (Errors.class.isAssignableFrom(type)) {
            persistent = false;
        }
        this.defaultConstraints = defaultConstraints;
    }

    /**
     * Evaluates the fetchmode.
     */
    @SuppressWarnings("rawtypes")
    private void establishFetchMode() {
        Map fetchMap = domainClass.getPropertyValue(GrailsDomainClassProperty.FETCH_MODE, Map.class);
        if (fetchMap != null && fetchMap.containsKey(name)) {
            if ("eager".equals(fetchMap.get(name))) {
                fetchMode = FETCH_EAGER;
            }
        }
    }

    /**
     * Checks whether this property is transient
     *
     * @param transientProps The transient properties
     */
    @SuppressWarnings("rawtypes")
    private void checkIfTransient(List transientProps) {
        if (transientProps == null) {
            return;
        }

        for (Object currentObj : transientProps) {
            // make sure its a string otherwise ignore. Note: Again maybe a warning?
            if (currentObj instanceof String) {
                String propertyName = (String)currentObj;
                // if the property name is on the not persistant list
                // then set persistant to false
                if (propertyName.equals(name)) {
                    persistent = false;
                    break;
                }
            }
        }
    }

    /**
     * Retrieves the transient properties
     *
     * @return A list of transient properties
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private List getTransients() {
        List allTransientProps = new ArrayList();

        List<Class<?>> allClasses = getAllDomainClassesInHierarchy();
        for(Class currentClass : allClasses) {
            Object transientProperty = GrailsClassUtils.getStaticPropertyValue(currentClass, TRANSIENT);
            if(transientProperty instanceof List) {
                List transientList = (List) transientProperty;
                allTransientProps.addAll(transientList);
            }
        }
        
        return allTransientProps;
    }
    
    private List<Class<?>> getAllDomainClassesInHierarchy() {
        List<Class<?>> classesInHierarchy = new ArrayList<Class<?>>();
        
        Class<?> currentClass = domainClass.getClazz();
        while(currentClass != null) {
            classesInHierarchy.add(currentClass);
            Class<?> superClass = currentClass.getSuperclass();
            currentClass = DomainClassArtefactHandler.isDomainClass(superClass) ? superClass : null;
        }
        return classesInHierarchy;
    }

    /* (non-Javadoc)
     * @see org.codehaus.groovy.grails.domain.GrailsDomainClassProperty#getName()
     */<commit_msg>fix failing test<commit_after>/* Copyright 2004-2005 the original author or authors.
 *
 * 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 org.codehaus.groovy.grails.commons;

import grails.util.GrailsNameUtils;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.codehaus.groovy.grails.validation.ConstrainedProperty;
import org.codehaus.groovy.grails.validation.ConstraintsEvaluator;
import org.codehaus.groovy.grails.validation.DefaultConstraintEvaluator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

/**
 * Represents a property of a domain class and contains meta information about the
 * properties relationships, naming conventions and type.
 *
 * @author <NAME>
 * @since 0.1
 */
public class DefaultGrailsDomainClassProperty implements GrailsDomainClassProperty {

    private GrailsDomainClass domainClass;
    private boolean persistent = true; // persistant by default
    private boolean identity;
    private boolean oneToMany;
    private String name;
    private Class<?> type;
    private boolean manyToMany;
    private boolean manyToOne;
    private boolean oneToOne;
    private boolean hasOne = false;
    private boolean bidirectional;
    private boolean derived = false;

    private Class<?> referencedPropertyType;
    private GrailsDomainClass referencedDomainClass;
    private GrailsDomainClassProperty otherSide;
    private String naturalName;
    private boolean inherited;
    private int fetchMode = FETCH_LAZY;
    private boolean owningSide;
    private String referencePropertyName;
    private boolean embedded;
    private GrailsDomainClass component;
    private boolean basicCollectionType;
    private Map<String, Object> defaultConstraints;

    /**
     * Constructor.
     * @param domainClass
     * @param descriptor
     */
    @SuppressWarnings("rawtypes")
    public DefaultGrailsDomainClassProperty(GrailsDomainClass domainClass, PropertyDescriptor descriptor) {
        this(domainClass, descriptor, null);
    }

    /**
     * Constructor.
     * @param domainClass
     * @param descriptor
     */
    @SuppressWarnings("rawtypes")
    public DefaultGrailsDomainClassProperty(GrailsDomainClass domainClass, PropertyDescriptor descriptor, Map<String, Object> defaultConstraints) {
        this.domainClass = domainClass;
        name = descriptor.getName();
        naturalName = GrailsNameUtils.getNaturalName(descriptor.getName());
        type = descriptor.getPropertyType();
        identity = descriptor.getName().equals(IDENTITY);

        // establish if property is persistant
        if (domainClass != null) {
            // figure out if this property is inherited
            if (!domainClass.isRoot()) {
                inherited = GrailsClassUtils.isPropertyInherited(domainClass.getClazz(), name);
            }
            List transientProps = getTransients();
            checkIfTransient(transientProps);

            establishFetchMode();
        }

        if (descriptor.getReadMethod() == null || descriptor.getWriteMethod() == null) {
            persistent = false;
        }

        if (Errors.class.isAssignableFrom(type)) {
            persistent = false;
        }
        this.defaultConstraints = defaultConstraints;
    }

    /**
     * Evaluates the fetchmode.
     */
    @SuppressWarnings("rawtypes")
    private void establishFetchMode() {
        Map fetchMap = domainClass.getPropertyValue(GrailsDomainClassProperty.FETCH_MODE, Map.class);
        if (fetchMap != null && fetchMap.containsKey(name)) {
            if ("eager".equals(fetchMap.get(name))) {
                fetchMode = FETCH_EAGER;
            }
        }
    }

    /**
     * Checks whether this property is transient
     *
     * @param transientProps The transient properties
     */
    @SuppressWarnings("rawtypes")
    private void checkIfTransient(List transientProps) {
        if (transientProps == null) {
            return;
        }

        for (Object currentObj : transientProps) {
            // make sure its a string otherwise ignore. Note: Again maybe a warning?
            if (currentObj instanceof String) {
                String propertyName = (String)currentObj;
                // if the property name is on the not persistant list
                // then set persistant to false
                if (propertyName.equals(name)) {
                    persistent = false;
                    break;
                }
            }
        }
    }

    /**
     * Retrieves the transient properties
     *
     * @return A list of transient properties
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private List getTransients() {
        List allTransientProps = new ArrayList();

        List<Class<?>> allClasses = getAllDomainClassesInHierarchy();
        for(Class currentClass : allClasses) {
            ClassPropertyFetcher propertyFetcher = ClassPropertyFetcher.forClass(currentClass);
            Object transientProperty = propertyFetcher.getPropertyValue(TRANSIENT, false);
            if(transientProperty instanceof List) {
                List transientList = (List) transientProperty;
                allTransientProps.addAll(transientList);
            }
        }
        
        return allTransientProps;
    }
    
    private List<Class<?>> getAllDomainClassesInHierarchy() {
        List<Class<?>> classesInHierarchy = new ArrayList<Class<?>>();
        
        Class<?> currentClass = domainClass.getClazz();
        while(currentClass != null) {
            classesInHierarchy.add(currentClass);
            Class<?> superClass = currentClass.getSuperclass();
            currentClass = DomainClassArtefactHandler.isDomainClass(superClass) ? superClass : null;
        }
        return classesInHierarchy;
    }

    /* (non-Javadoc)
     * @see org.codehaus.groovy.grails.domain.GrailsDomainClassProperty#getName()
     */
{'fraction_non_alphanumeric': 0.08442974212465228, 'fraction_numerical': 0.0021051048793323812, 'mean_word_length': 2.8027444253859346, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '145798', 'n_tokens_mistral': 3415, 'n_tokens_neox': 3318, 'n_words': 907}