// Path: core/src/main/java/net/sf/beanlib/CollectionPropertyName.java
// public class CollectionPropertyName<T> {
// 
//     public static final CollectionPropertyName<?>[] EMPTY_ARRAY = {};
// 
//     private final Class<T> declaringClass;
// 
//     private final String collectionProperty;
// 
//     private final int hashCode;
// 
//     private final BeanGetter beanGetter = new BeanGetter();
// 
//     /** Convenient factory method. */
//     public static <T> CollectionPropertyName<T>[] createCollectionPropertyNames(Class<T> declaringClass, String[] collectionProperties) {
//         Set<CollectionPropertyName<T>> set = new HashSet<>();
// 
//         for (String s : collectionProperties) {
//             set.add(new CollectionPropertyName<>(declaringClass, s));
//         }
// 
//         @SuppressWarnings("unchecked")
//         CollectionPropertyName<T>[] ret = (CollectionPropertyName<T>[]) set.toArray(EMPTY_ARRAY);
//         return ret;
//     }
// 
//     /**
//      * @param declaringClass declaring class of the Collection or Map property.
//      * @param collectionProperty Collection or Map property name.
//      */
//     public CollectionPropertyName(Class<T> declaringClass, String collectionProperty) {
//         this.declaringClass = declaringClass;
//         this.collectionProperty = collectionProperty;
//         this.hashCode = beanGetter.getBeanHashCode(this);
//     }
// 
//     public Class<T> getDeclaringClass() {
//         return declaringClass;
//     }
// 
//     public String getCollectionProperty() {
//         return collectionProperty;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (!(obj instanceof CollectionPropertyName)) {
//             return false;
//         }
//         CollectionPropertyName<?> that = (CollectionPropertyName<?>) obj;
//         return new EqualsBuilder().append(this.declaringClass, that.declaringClass).append(this.collectionProperty, that.collectionProperty)
//                 .isEquals();
//     }
// 
//     @Override
//     public int hashCode() {
//         return this.hashCode;
//     }
// }
// 
// Path: core/src/main/java/net/sf/beanlib/spi/PropertyFilter.java
// public interface PropertyFilter {
// 
//     /**
//      * Returns true if the given JavaBean property should be propagated; false otherwise.
//      *
//      * @param propertyName JavaBean property name.
//      * @param readerMethod reader method of the JavaBean property name.
//      * @return true if the given JavaBean property should be propagated.
//      */
//     boolean propagate(String propertyName, Method readerMethod);
// }


import static net.sf.beanlib.utils.ClassUtils.fqcn;
import static net.sf.beanlib.utils.ClassUtils.immutable;
import static net.sf.beanlib.utils.ClassUtils.isJavaPackage;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import net.sf.beanlib.CollectionPropertyName;
import net.sf.beanlib.spi.PropertyFilter;
/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * 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 net.sf.beanlib.hibernate;




/**
 * A default implementation used to determine if a Hibernate property that follows the JavaBean getter/setter convention
 * should be propagated. Each propagation decision can be controlled by specifying
 * <ul>
 * <li>An application package prefix used to determine if a property with a type of an entity bean class will be
 * included for replication;</li>
 * <li>The set of entity bean classes for matching properties that will be replicated;</li>
 * <li>The set of collection and map properties that will be replicated;</li>
 * <li>A {@link net.sf.beanlib.spi.PropertyFilter vetoer} used to veto the propagation of a property</li>
 * </ul>
 *
 * @author Joe D. Velopar
 */
public class HibernatePropertyFilter implements PropertyFilter {

    /**
     * The set of entity bean classes for matching properties that will be replicated, eagerly fetching if necessary.
     * Null means all whereas empty means none.
     */
    private Set<Class<?>> entityBeanClassSet;

    /**
     * The set of collection and map properties that will be replicated, eagerly fetching if necessary. Null means all
     * whereas empty means none.
     */
// Path: core/src/main/java/net/sf/beanlib/CollectionPropertyName.java
// public class CollectionPropertyName<T> {
// 
//     public static final CollectionPropertyName<?>[] EMPTY_ARRAY = {};
// 
//     private final Class<T> declaringClass;
// 
//     private final String collectionProperty;
// 
//     private final int hashCode;
// 
//     private final BeanGetter beanGetter = new BeanGetter();
// 
//     /** Convenient factory method. */
//     public static <T> CollectionPropertyName<T>[] createCollectionPropertyNames(Class<T> declaringClass, String[] collectionProperties) {
//         Set<CollectionPropertyName<T>> set = new HashSet<>();
// 
//         for (String s : collectionProperties) {
//             set.add(new CollectionPropertyName<>(declaringClass, s));
//         }
// 
//         @SuppressWarnings("unchecked")
//         CollectionPropertyName<T>[] ret = (CollectionPropertyName<T>[]) set.toArray(EMPTY_ARRAY);
//         return ret;
//     }
// 
//     /**
//      * @param declaringClass declaring class of the Collection or Map property.
//      * @param collectionProperty Collection or Map property name.
//      */
//     public CollectionPropertyName(Class<T> declaringClass, String collectionProperty) {
//         this.declaringClass = declaringClass;
//         this.collectionProperty = collectionProperty;
//         this.hashCode = beanGetter.getBeanHashCode(this);
//     }
// 
//     public Class<T> getDeclaringClass() {
//         return declaringClass;
//     }
// 
//     public String getCollectionProperty() {
//         return collectionProperty;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (!(obj instanceof CollectionPropertyName)) {
//             return false;
//         }
//         CollectionPropertyName<?> that = (CollectionPropertyName<?>) obj;
//         return new EqualsBuilder().append(this.declaringClass, that.declaringClass).append(this.collectionProperty, that.collectionProperty)
//                 .isEquals();
//     }
// 
//     @Override
//     public int hashCode() {
//         return this.hashCode;
//     }
// }
// 
// Path: core/src/main/java/net/sf/beanlib/spi/PropertyFilter.java
// public interface PropertyFilter {
// 
//     /**
//      * Returns true if the given JavaBean property should be propagated; false otherwise.
//      *
//      * @param propertyName JavaBean property name.
//      * @param readerMethod reader method of the JavaBean property name.
//      * @return true if the given JavaBean property should be propagated.
//      */
//     boolean propagate(String propertyName, Method readerMethod);
// }


// Path: hibernate/src/main/java/net/sf/beanlib/hibernate/HibernatePropertyFilter.java
import static net.sf.beanlib.utils.ClassUtils.fqcn;
import static net.sf.beanlib.utils.ClassUtils.immutable;
import static net.sf.beanlib.utils.ClassUtils.isJavaPackage;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import net.sf.beanlib.CollectionPropertyName;
import net.sf.beanlib.spi.PropertyFilter;

/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * 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 net.sf.beanlib.hibernate;




/**
 * A default implementation used to determine if a Hibernate property that follows the JavaBean getter/setter convention
 * should be propagated. Each propagation decision can be controlled by specifying
 * <ul>
 * <li>An application package prefix used to determine if a property with a type of an entity bean class will be
 * included for replication;</li>
 * <li>The set of entity bean classes for matching properties that will be replicated;</li>
 * <li>The set of collection and map properties that will be replicated;</li>
 * <li>A {@link net.sf.beanlib.spi.PropertyFilter vetoer} used to veto the propagation of a property</li>
 * </ul>
 *
 * @author Joe D. Velopar
 */
public class HibernatePropertyFilter implements PropertyFilter {

    /**
     * The set of entity bean classes for matching properties that will be replicated, eagerly fetching if necessary.
     * Null means all whereas empty means none.
     */
    private Set<Class<?>> entityBeanClassSet;

    /**
     * The set of collection and map properties that will be replicated, eagerly fetching if necessary. Null means all
     * whereas empty means none.
     */
    private Set<? extends CollectionPropertyName<?>> collectionPropertyNameSet;