alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Groovy example source code file (MixinTest.groovy)

This example Groovy source code file (MixinTest.groovy) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Groovy tags/keywords

arraylistext, closure, linkedhashset, linkedhashset, linkedlist, list, list, object, object, objtotest, overflow_a, reentrantlock, set, set

The Groovy MixinTest.groovy source code

/*
 * Copyright 2003-2009 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 groovy.lang

import java.util.concurrent.locks.ReentrantLock
import org.codehaus.groovy.reflection.ClassInfo

class MixinTest extends GroovyTestCase {

    protected void setUp() {
        ClassInfo.clearModifiedExpandos()
    }

    protected void tearDown() {
        ArrayList.metaClass = null
        List.metaClass = null
    }

    void testOneClass() {
        List.mixin ListExt
        ArrayList.mixin ArrayListExt
        assertEquals 1, [0, 1].swap()[0]
        assertEquals 0, [0, 1].swap()[1]
        assertEquals 0, [0, 1].swap().unswap()[0]
        assertEquals 1, [0, 1].swap().unswap()[1]
    }

    void testWithList() {
        ArrayList.mixin ArrayListExt, ListExt
        assertEquals 1, [0, 1].swap()[0]
        assertEquals 0, [0, 1].swap()[1]
        assertEquals 0, [0, 1].swap().unswap()[0]
        assertEquals 1, [0, 1].swap().unswap()[1]
    }

    void testCombined() {
        ArrayList.mixin Combined
        assertEquals 1, [0, 1].swap()[0]
        assertEquals 0, [0, 1].swap()[1]
        assertEquals 0, [0, 1].swap().unswap()[0]
        assertEquals 1, [0, 1].swap().unswap()[1]
    }

    void testWithEmc() {
        ArrayList.metaClass.unswap = {
            [delegate[1], delegate[0]]
        }
        ArrayList.mixin ArrayListExt
        assertEquals 1, [0, 1].swap()[0]
        assertEquals 0, [0, 1].swap()[1]
        assertEquals 0, [0, 1].swap().unswap()[0]
        assertEquals 1, [0, 1].swap().unswap()[1]
    }

    void testGroovyObject() {
        def obj = new ObjToTest()
        assertEquals "original", obj.value
        obj.metaClass.mixin ObjToTestCategory
        assertEquals "changed by category", obj.value
        assertEquals "original", new ObjToTest().value
    }

    void testGroovyObjectWithEmc() {
        ObjToTest.metaClass.getValue = {->
            "emc changed"
        }
        ObjToTest obj = new ObjToTest()
        assertEquals "emc changed", obj.getValue()
        obj.metaClass.mixin ObjToTestCategory
        assertEquals "changed by category", obj.value
        assertEquals "emc changed", new ObjToTest().value
    }

    void testFlatten() {
        Object.metaClass.mixin DeepFlattenToCategory
        assertEquals([8, 9, 3, 2, 1, 4], [[8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo() as List)

        def x = [-2, -2, -3, -3]
        x.metaClass.mixin NoFlattenArrayListCategory
        assertEquals([x, 8, 9, 3, 2, 1, 4], [x, [8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo() as List)

        x.metaClass = null
        x.metaClass.flattenTo = {Set set -> set << delegate }
        assertEquals([x, 8, 9, 3, 2, 1, 4], [x, [8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo() as List)

        x.metaClass = null
        Object.metaClass.flattenTo(ArrayList) {->
            LinkedHashSet set = new LinkedHashSet()
            delegate.flattenTo(set)
            return set
        }
        Object.metaClass.flattenTo(ArrayList) {Set set ->
            set << "oops"
            return Collection.metaClass.invokeMethod(delegate, "flattenTo", set)
        }
        ArrayList.metaClass = null
        assertEquals(["oops", -2, -3, 8, 9, 3, 2, 1, 4], [x, [8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo() as List)

        ArrayList.metaClass = null
        Object.metaClass {
            flattenTo(ArrayList) {->
                LinkedHashSet set = new LinkedHashSet()
                delegate.flattenTo(set)
                return set
            }

            flattenTo(ArrayList) {Set set ->
                set << "oopsssss"
                return Collection.metaClass.invokeMethod(delegate, "flattenTo", set)
            }

            asList {->
                delegate as List
            }
        }
        assertEquals(["oopsssss", -2, -3, 8, 9, 3, 2, 1, 4], [x, [8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo().asList())

        ArrayList.metaClass = null
        Object.metaClass {
            define(ArrayList) {
                flattenTo {->
                    LinkedHashSet set = new LinkedHashSet()
                    delegate.flattenTo(set)
                    return set
                }

                flattenTo {Set set ->
                    set << "ssoops"
                    return Collection.metaClass.invokeMethod(delegate, "flattenTo", set)
                }
            }

            asList {->
                delegate as List
            }
        }
        assertEquals(["ssoops", -2, -3, 8, 9, 3, 2, 1, 4], [x, [8, 9] as Object[], [3, 2, [2: 1, 3: 4]], [2, 3]].flattenTo().asList())

        Object.metaClass = null
    }

    void _testMixingLockable() {
        Object.metaClass.mixin ReentrantLock
        def name = "abcdef"
        name.lock()
        try {
            assertTrue name.isLocked()
        }
        finally {
            name.unlock()
        }
        Object.metaClass = null
    }

    void testConcurrentQueue() {
        ReentrantLock.metaClass {
            withLock {Closure operation ->
                lock()
                try {
                    operation()
                }
                finally {
                    unlock()
                }
            }
        }

        def queue = new ConcurrentQueue()
        queue.put 1
        queue.put 2
        queue.put 3
        assertEquals 1, queue.get()
        assertEquals 2, queue.get()
        assertEquals 3, queue.get()

        ReentrantLock.metaClass = null
    }

    void testDynamicConcurrentQueue() {
        ReentrantLock.metaClass {
            withLock {Closure operation ->
                lock()
                try {
                    operation()
                }
                finally {
                    unlock()
                }
            }
        }

        def queue = new Object()
        queue.metaClass {
            mixin LinkedList, ReentrantLock

            get {->
                withLock {
                    removeFirst()
                }
            }

            put {obj ->
                withLock {
                    addLast(obj)
                }
            }
        }

        queue.put 1
        queue.put 2
        queue.put 3
        assertEquals 1, queue.get()
        assertEquals 2, queue.get()
        assertEquals 3, queue.get()

        queue.metaClass {
            iterator {->
                mixedIn[LinkedList].iterator()
            }

            duplicateEachElement {
                withLock {
                    LinkedList newList = new LinkedList()
                    mixedIn[LinkedList].each {
                        newList << it
                        newList << it
                    }
                    mixedIn[LinkedList] = newList
                }
            }
        }

        queue.put 1
        queue.put 2
        queue.put 3
        queue.duplicateEachElement()
        assertEquals 1, queue.get()
        assertEquals 1, queue.get()
        assertEquals 2, queue.get()
        assertEquals 2, queue.get()
        assertEquals 3, queue.get()
        assertEquals 3, queue.get()

        ReentrantLock.metaClass = null
    }

    void testNoDupCollection() {
        def list = new Object()
        list.metaClass {
            mixin NoDuplicateCollection, LinkedList

            find = {Closure check ->
                mixedIn[LinkedList].find(check)
            }
        }

        list.put 1
        list.put 1
        list.put 2
        list.put 2
        list.put 3
        list.put 3

        assertEquals(3, list.size())
        assertEquals 1, list[0]
        assertEquals 2, list[1]
        assertEquals 3, list[2]
    }

    void testList() {
        def u = []
        u.metaClass {
            mixin HashSet

            leftShift {obj ->
                mixedIn[List] << obj
                mixedIn[Set] << obj
            }
        }

        u << 1
        u << 2
        u << 1
        u << 2
        u << 1
        u << 2

        assertEquals 6, u.size()
        assertEquals 6, ((List) u).size()
        assertEquals 6, ((Collection) u).size()
        assertEquals 2, u.mixedIn[Set].size()
        assertEquals 2, ((Set) u).size()
    }

    void testWPM() {

        new WPM_B().foo()

        WPM_C.metaClass { mixin WPM_B }

        def c = new WPM_C()
        c.foo()
        c.foobar()
    }

    void testStackOverflow() {
        Overflow_B.metaClass {
            mixin Overflow_A

            foo = {->
                println 'New foo ' + receive('')
            }
        }

        final Overflow_A a = new Overflow_A()
        a.foo()

        final Overflow_B b = new Overflow_B()
        b.foo()
    }

    void testStackOverflowErrorWithMixinsAndClosure() {
        assertScript """
            class Groovy3474A {
                int counter = 1
                protected def final foo() {
                    bar { counter }
                }
                private final String bar(Closure code) { 
                    return "Bar " + code() 
                }
            }
            
            class Groovy3474B extends Groovy3474A {}
            
            class Groovy3474C {}
            Groovy3474C.metaClass { mixin Groovy3474B }
            def c = new Groovy3474C()
            assert c.foo() == 'Bar 1'
            println "testStackOverflowErrorWithMixinsAndClosure() Done"
        """
    }

    void testMixinWithVarargs() {
        assertScript """
            class Dsl {
                static novarargs(java.util.List s) { "novarargs" + s.size() }
                static plainVarargs(Object... s) { "plainVarargs" + s.size() }
                static mixedVarargs(int foo, String... s) { "mixedVarargs" + s.size() }
            }
            this.metaClass.mixin(Dsl)
            assert novarargs(["a", "b"]) == "novarargs2"
            assert plainVarargs("a", "b", 35) == "plainVarargs3"
            assert mixedVarargs(3, "a", "b", "c", "d") == "mixedVarargs4"
        """
    }
}

class ArrayListExt {
    static def swap(ArrayList self) {
        [self[1], self[0]]
    }
}

class ListExt {
    static def unswap(List self) {
        [self[1], self[0]]
    }
}

class Combined {
    static def swap(ArrayList self) {
        [self[1], self[0]]
    }

    static def unswap(List self) {
        [self[1], self[0]]
    }
}

class ObjToTest {
    def getValue() {
        "original"
    }
}

class ObjToTestCategory {
    def static getValue(ObjToTest self) {
        "changed by category"
    }
}

class DeepFlattenToCategory {
    static Set flattenTo(element) {
        LinkedHashSet set = new LinkedHashSet()
        element.flattenTo(set)
        return set
    }

    // Object - put to result set
    static void flattenTo(element, Set addTo) {
        addTo << element
    }

    // Collection - flatten each element
    static void flattenTo(Collection elements, Set addTo) {
        elements.each {element ->
            element.flattenTo(addTo)
        }
    }

    // Map - flatten each value
    static void flattenTo(Map elements, Set addTo) {
        elements.values().flattenTo(addTo)
    }

    // Array - flatten each element
    static void flattenTo(Object[] elements, Set addTo) {
        elements.each {element ->
            element.flattenTo(addTo)
        }
    }
}

class NoFlattenArrayListCategory {
    // Object - put to result set

    static void flattenTo(ArrayList element, Set addTo) {
        addTo << element
    }
}

class ConcurrentQueue {
    static {
        ConcurrentQueue.metaClass.mixin LinkedList, ReentrantLock
    }

    def get() {
        withLock {
            removeFirst()
        }
    }

    void put(def obj) {
        withLock {
            addLast(obj)
        }
    }
}

class NoDuplicateCollection {
    void put(def obj) {
        def clone = find {
            it == obj
        }

        if (!clone)
            add obj
    }
}

class WPM_A {

    def final foo() {
        bar()
    }

    private final String bar() { return "Bar" }
}

class WPM_B extends WPM_A {
    def foobar() {
        super.foo()
    }
}

class WPM_C {}

class Overflow_A {
    public void foo() {
        println 'Original foo ' + receive('')
    }

    protected Object receive() {
        return "Message"
    }

    protected Object receive(Object param) {
        receive() + param
    }
}

class Overflow_B {}

Other Groovy examples (source code examples)

Here is a short list of links related to this Groovy MixinTest.groovy source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.