com.link_intersystems.lang.reflect.criteria.MemberCriteriaTest.java Source code

Java tutorial

Introduction

Here is the source code for com.link_intersystems.lang.reflect.criteria.MemberCriteriaTest.java

Source

/**
 * Copyright 2011 Link Intersystems GmbH <rene.link@link-intersystems.com>
 *
 * 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 com.link_intersystems.lang.reflect.criteria;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.Serializable;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.collections4.Predicate;
import org.junit.Before;
import org.junit.Test;

import com.link_intersystems.lang.reflect.AccessType;
import com.link_intersystems.lang.reflect.ReflectFacade;
import com.link_intersystems.lang.reflect.SignaturePredicate;
import com.link_intersystems.lang.reflect.criteria.ClassCriteria.ClassType;
import com.link_intersystems.lang.reflect.criteria.ClassCriteria.TraverseStrategy;
import com.link_intersystems.lang.reflect.criteria.MemberCriteria.IterateStrategy;

public class MemberCriteriaTest {

    private MemberCriteria memberCriteria;

    @Before
    public void setup() {
        memberCriteria = new MemberCriteria();
    }

    @Test(expected = IllegalArgumentException.class)
    public void nullMemberIterateOrderComparator() {
        memberCriteria.setMemberIterateOrder(null);
    }

    @Test
    public void defaultMemberIterator() {
        Iterable<Class<?>> classIterable = new ClassCriteria().getIterable(Object.class);
        Iterable<Member> iterable = memberCriteria.getIterable(classIterable);
        assertNotNull(iterable);
        Iterator<Member> iterator = iterable.iterator();
        assertNotNull(iterator);
        assertTrue(iterator.hasNext());
        Member next = iterator.next();
        assertNotNull(next);

    }

    @Test
    public void annotatedElementIterator() {
        Iterable<Class<?>> classIterable = new ClassCriteria().getIterable(Object.class);
        Iterable<? extends AnnotatedElement> iterable = memberCriteria.getAnnotatedElementIterable(classIterable);
        assertNotNull(iterable);
        Iterator<? extends AnnotatedElement> iterator = iterable.iterator();
        assertNotNull(iterator);
        assertTrue(iterator.hasNext());
        AnnotatedElement next = iterator.next();
        assertNotNull(next);

    }

    @Test
    public void notAllowdModifiers() throws IllegalAccessException {
        Field[] declaredFields = Modifier.class.getDeclaredFields();
        int maxModifierValue = 0;
        for (Field field : declaredFields) {
            int modifiers = field.getModifiers();
            if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
                    && field.getType().equals(Integer.TYPE)) {
                try {
                    Integer value = (Integer) field.get(Modifier.class);
                    maxModifierValue = Math.max(maxModifierValue, value.intValue());
                } catch (IllegalArgumentException e) {
                    throw new AssertionError(e);
                }
            }
        }
        maxModifierValue = maxModifierValue << 2;
        try {
            memberCriteria.withModifiers(maxModifierValue);
            throw new AssertionError("modifiers are not allowed");
        } catch (IllegalArgumentException e) {
            String message = e.getMessage();
            assertTrue(message.startsWith("modifiers must be"));
        }
    }

    @SuppressWarnings("unchecked")
    @Test
    public void publicAbstractMethodStartingWithAdd() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.withModifiers(Modifier.ABSTRACT);
        memberCriteria.named(Pattern.compile("add.*"));
        memberCriteria.setMemberIterateOrder(ReflectFacade.getMemberNameComparator());
        Collection<Class<?>> iteratedTypes = new ArrayList<Class<?>>(Arrays.asList(List.class, Collection.class));
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a method", member instanceof Method);
            iteratedTypes.remove(member.getDeclaringClass());
            String name = member.getName();
            assertTrue(name.startsWith("add"));
            int modifiers = member.getModifiers();
            assertTrue(Modifier.isAbstract(modifiers));
        }
        assertTrue("Some types have not been iterated. " + iteratedTypes, iteratedTypes.isEmpty());
    }

    @Test
    public void getFirstMethodWithSameSignatureAsCollectionAddObject()
            throws SecurityException, NoSuchMethodException {
        memberCriteria.setResult(Result.FIRST);
        memberCriteria.membersOfType(Method.class);

        Method method = List.class.getDeclaredMethod("isEmpty");

        memberCriteria.add(new SignaturePredicate(method));

        ClassCriteria classCriteria = new ClassCriteria();
        classCriteria.setTraverseStrategy(TraverseStrategy.DEPTH_FIRST);
        classCriteria.setSelection(ClassType.CLASSES);
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);

        Iterator<Member> criteriaIterator = memberIterable.iterator();
        Member member = criteriaIterator.next();
        Method firstMatch = (Method) member;
        Method declaredMethod = ArrayList.class.getDeclaredMethod("isEmpty");
        assertEquals(declaredMethod, firstMatch);
        assertFalse(criteriaIterator.hasNext());
    }

    @Test
    public void hierarchyTraveral() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.withModifiers(Modifier.ABSTRACT);
        memberCriteria.named(Pattern.compile("add.*"));
        Class<?> currentHierarchyClass = ArrayList.class;
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a method", member instanceof Method);
            if (!currentHierarchyClass.equals(member.getDeclaringClass())) {
                if (!member.getDeclaringClass().isInterface()) {
                    assertTrue("members must be iterated " + "from subclass to superclass",
                            ((Class<?>) member.getDeclaringClass()).isAssignableFrom(currentHierarchyClass));
                    // so the current declaring class is not the members
                    // declaring
                    // class which means we went up the hierarchy
                    currentHierarchyClass = member.getDeclaringClass();
                }
            }
        }
    }

    @Test
    public void publicMethods() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.withAccess(AccessType.PUBLIC);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a method", member instanceof Method);
            int modifiers = member.getModifiers();
            assertTrue(Modifier.isPublic(modifiers));
            assertFalse(Modifier.isProtected(modifiers));
            assertFalse(Modifier.isPrivate(modifiers));
        }
    }

    @Test
    public void defaultAccessMethods() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.withAccess(AccessType.DEFAULT);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(Class.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a method", member instanceof Method);
            int modifiers = member.getModifiers();
            assertFalse(Modifier.isPublic(modifiers));
            assertFalse(Modifier.isProtected(modifiers));
            assertFalse(Modifier.isPrivate(modifiers));
        }
    }

    @Test
    public void defaultAccessMethodsWithStaticNativeOnly() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.withAccess(AccessType.DEFAULT);
        memberCriteria.withModifiers(Modifier.STATIC | Modifier.NATIVE);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(Class.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a method", member instanceof Method);
            int modifiers = member.getModifiers();
            assertFalse(Modifier.isPublic(modifiers));
            assertFalse(Modifier.isProtected(modifiers));
            assertFalse(Modifier.isPrivate(modifiers));
            assertTrue(Modifier.isStatic(modifiers));
            assertTrue(Modifier.isNative(modifiers));
        }
    }

    @Test
    public void usingFilterTest() {
        memberCriteria.membersOfType(Method.class);
        memberCriteria.add(new ToStringPredicate());
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(Object.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        Iterator<Member> iterator = memberIterable.iterator();
        assertTrue(iterator.hasNext());
        Member member = iterator.next();
        int modifiers = member.getModifiers();
        assertTrue(Modifier.isPublic(modifiers));
        assertFalse(iterator.hasNext());
    }

    @Test
    public void privateStaticFields() {
        memberCriteria.membersOfType(Field.class);
        memberCriteria.withAccess(AccessType.PRIVATE);
        memberCriteria.withModifiers(Modifier.STATIC);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(Class.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a field", member instanceof Field);
            int modifiers = member.getModifiers();
            assertFalse(Modifier.isPublic(modifiers));
            assertFalse(Modifier.isProtected(modifiers));
            assertTrue(Modifier.isPrivate(modifiers));
            assertTrue(Modifier.isStatic(modifiers));
        }
    }

    @Test
    public void protecedConstructors() {
        memberCriteria.membersOfType(Constructor.class);
        memberCriteria.withAccess(AccessType.PROTECTED);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        assertTrue(memberIterable.iterator().hasNext());
        for (Member member : memberIterable) {
            assertTrue("member must be a constructor", member instanceof Constructor<?>);
            int modifiers = member.getModifiers();
            assertFalse(Modifier.isPublic(modifiers));
            assertTrue(Modifier.isProtected(modifiers));
            assertFalse(Modifier.isPrivate(modifiers));
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void illegalMemeberTypes() {
        memberCriteria.membersOfType(String.class);
    }

    @Test(expected = IllegalArgumentException.class)
    public void illegalModifierPrivate() {
        memberCriteria.withModifiers(Modifier.PRIVATE);
    }

    @Test(expected = IllegalArgumentException.class)
    public void illegalModifierPublic() {
        memberCriteria.withModifiers(Modifier.PUBLIC);
    }

    @Test(expected = IllegalArgumentException.class)
    public void illegalModifierProtected() {
        memberCriteria.withModifiers(Modifier.PROTECTED);
    }

    @Test(expected = IllegalStateException.class)
    public void iteratorRemove() {
        memberCriteria.membersOfType(Field.class);
        memberCriteria.withAccess(AccessType.PRIVATE);
        memberCriteria.withModifiers(Modifier.STATIC);
        ClassCriteria classCriteria = new ClassCriteria();
        Iterable<Class<?>> classIterable = classCriteria.getIterable(Class.class);
        Iterable<Member> memberIterable = memberCriteria.getIterable(classIterable);
        Iterator<Member> iterator = memberIterable.iterator();
        assertTrue(iterator.hasNext());
        iterator.remove();
    }

    @Test(expected = IllegalArgumentException.class)
    @SuppressWarnings("all")
    public void withNullAccesses() {
        memberCriteria.withAccess(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void withEmptyAccesses() {
        memberCriteria.withAccess(new AccessType[0]);
    }

    @Test
    public void annotatedElementsPackage2Class2Member() throws SecurityException, NoSuchMethodException {
        ClassCriteria classCriteria = new ClassCriteria();
        classCriteria.setSelection(ClassType.CLASSES);
        memberCriteria.membersOfType(Method.class);
        memberCriteria.named("size");
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<? extends AnnotatedElement> annotatedElementIterable = memberCriteria
                .getAnnotatedElementIterable(classIterable, IterateStrategy.PACKAGE_CLASS_MEMBERS);
        Iterator<? extends AnnotatedElement> iterator = annotatedElementIterable.iterator();
        assertTrue(iterator.hasNext());
        AnnotatedElement next = iterator.next();
        assertEquals(ArrayList.class.getPackage(), next);
        next = iterator.next();
        assertEquals(ArrayList.class, next);
        next = iterator.next();
        assertEquals(ArrayList.class.getDeclaredMethod("size"), next);
        next = iterator.next();
        assertEquals(AbstractList.class.getPackage(), next);
        next = iterator.next();
        assertEquals(AbstractList.class, next);
        next = iterator.next();
        assertEquals(AbstractCollection.class.getPackage(), next);
        next = iterator.next();
        assertEquals(AbstractCollection.class, next);
        next = iterator.next();
        assertEquals(AbstractCollection.class.getDeclaredMethod("size"), next);
        next = iterator.next();
        assertEquals(Object.class.getPackage(), next);
        next = iterator.next();
        assertEquals(Object.class, next);
        assertFalse(iterator.hasNext());
    }

    @Test
    public void annotatedElementsMembers2Classes() throws SecurityException, NoSuchMethodException {
        ClassCriteria classCriteria = new ClassCriteria();
        classCriteria.setSelection(ClassType.CLASSES);
        memberCriteria.membersOfType(Method.class);
        memberCriteria.named("size");
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<? extends AnnotatedElement> annotatedElementIterable = memberCriteria
                .getAnnotatedElementIterable(classIterable, IterateStrategy.MEMBERS_CLASS);
        Iterator<? extends AnnotatedElement> iterator = annotatedElementIterable.iterator();
        assertTrue(iterator.hasNext());
        AnnotatedElement next = iterator.next();
        assertEquals(ArrayList.class.getDeclaredMethod("size"), next);
        next = iterator.next();
        assertEquals(ArrayList.class, next);
        next = iterator.next();
        assertEquals(AbstractList.class, next);
        next = iterator.next();
        assertEquals(AbstractCollection.class.getDeclaredMethod("size"), next);
        next = iterator.next();
        assertEquals(AbstractCollection.class, next);
        next = iterator.next();
        assertEquals(Object.class, next);
        assertFalse(iterator.hasNext());
    }

    @Test
    public void annotatedElementsPackagesOnly() throws SecurityException, NoSuchMethodException {
        ClassCriteria classCriteria = new ClassCriteria();
        classCriteria.setSelection(ClassType.CLASSES);
        memberCriteria.membersOfType(Method.class);
        memberCriteria.named("size");
        Iterable<Class<?>> classIterable = classCriteria.getIterable(ArrayList.class);
        Iterable<? extends AnnotatedElement> annotatedElementIterable = memberCriteria
                .getAnnotatedElementIterable(classIterable, IterateStrategy.PACKAGES_ONLY);
        Iterator<? extends AnnotatedElement> iterator = annotatedElementIterable.iterator();
        assertTrue(iterator.hasNext());
        AnnotatedElement next = iterator.next();
        assertEquals(ArrayList.class.getPackage(), next);
        next = iterator.next();
        assertEquals(AbstractList.class.getPackage(), next);
        next = iterator.next();
        assertEquals(AbstractCollection.class.getPackage(), next);
        next = iterator.next();
        assertEquals(Object.class.getPackage(), next);
        assertFalse(iterator.hasNext());
    }

    private static class ToStringPredicate implements Predicate, Serializable {

        /**
         *
         */
        private static final long serialVersionUID = 2067359829290114563L;

        public boolean evaluate(Object object) {
            Member member = (Member) object;
            return "toString".equals(member.getName());
        }
    }
}