package sk.nociar.jpacloner; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Factory of various {@link PropertyFilter}s. Example:<br/> * <pre> * PropertyFilter filter = PropertyFilterFactory.getAnnotationFilter(Id.class, Transient.class, Version.class); * Company cloned = JpaCloner.clone(company, filter, "department+.(boss|employees).address"); * </pre> * * @author Miroslav Nociar */ public class PropertyFilters { private PropertyFilters() { throw new UnsupportedOperationException(); } /** * Default property filter. */ private static final PropertyFilter defaultFilter = new PropertyFilter() { @Override public boolean test(Object entity, String property) { return true; } }; private static final class AnnotationFilter implements PropertyFilter { private final Class<? extends Annotation> clazz; private AnnotationFilter(Class<? extends Annotation> clazz) { if (clazz == null) { throw new NullPointerException(); } this.clazz = clazz; } @Override public boolean test(Object entity, String property) { if (entity == null) { return true; } JpaClassInfo classInfo = JpaClassInfo.get(entity.getClass()); if (classInfo == null) { return true; } JpaPropertyInfo propertyInfo = classInfo.getPropertyInfo(property); if (propertyInfo == null) { return true; } return propertyInfo.getAccessibleObject().getAnnotation(clazz) == null; } } private static final class ComposedFilter implements PropertyFilter { private final List<PropertyFilter> filters; private ComposedFilter(List<PropertyFilter> filters) { this.filters = filters; } @Override public boolean test(Object entity, String property) { for (PropertyFilter filter : filters) { if (filter.test(entity, property) != true) { // filter did not pass return false; } } return true; } } public static PropertyFilter getDefaultFilter() { return defaultFilter; } public static PropertyFilter getComposedFilter(PropertyFilter filter, PropertyFilter... filters) { List<PropertyFilter> all = new ArrayList<PropertyFilter>(); all.add(filter); if (filters != null) { all.addAll(Arrays.asList(filters)); } return new ComposedFilter(all); } public static PropertyFilter getAnnotationFilter(Class<? extends Annotation> clazz) { return new AnnotationFilter(clazz); } public static PropertyFilter getAnnotationFilter(Class<? extends Annotation> c1, Class<? extends Annotation> c2) { return getComposedFilter(getAnnotationFilter(c1), getAnnotationFilter(c2)); } public static PropertyFilter getAnnotationFilter(Class<? extends Annotation> c1, Class<? extends Annotation> c2, Class<? extends Annotation> c3) { return getComposedFilter(getAnnotationFilter(c1), getAnnotationFilter(c2), getAnnotationFilter(c3)); } public static PropertyFilter getAnnotationFilter(Class<? extends Annotation> c1, Class<? extends Annotation> c2, Class<? extends Annotation> c3, Class<? extends Annotation> c4) { return getComposedFilter(getAnnotationFilter(c1), getAnnotationFilter(c2), getAnnotationFilter(c3), getAnnotationFilter(c4)); } public static PropertyFilter getAnnotationFilter(Class<? extends Annotation> c1, Class<? extends Annotation> c2, Class<? extends Annotation> c3, Class<? extends Annotation> c4, Class<? extends Annotation> c5) { return getComposedFilter(getAnnotationFilter(c1), getAnnotationFilter(c2), getAnnotationFilter(c3), getAnnotationFilter(c4), getAnnotationFilter(c5)); } }