You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by pa...@apache.org on 2015/05/03 19:26:21 UTC

[2/4] incubator-groovy git commit: Add GroovyInterceptable section

Add GroovyInterceptable section


Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/15d5e647
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/15d5e647
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/15d5e647

Branch: refs/heads/GROOVY_2_4_X
Commit: 15d5e647097836e1cf25430d8702c5b0c211a544
Parents: fb4b17b
Author: Maksym Stavytskyi <st...@gmail.com>
Authored: Mon Mar 30 01:53:18 2015 +0300
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sun May 3 18:36:24 2015 +0200

----------------------------------------------------------------------
 src/spec/doc/core-metaprogramming.adoc          | 40 +++++++++++++++++++-
 .../metaprogramming/InterceptableTest.groovy    | 20 ++++++++++
 .../InterceptionThroughMetaClassTest.groovy     | 25 ++++++++++++
 3 files changed, 84 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/15d5e647/src/spec/doc/core-metaprogramming.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-metaprogramming.adoc b/src/spec/doc/core-metaprogramming.adoc
index b1e48b1..9312830 100644
--- a/src/spec/doc/core-metaprogramming.adoc
+++ b/src/spec/doc/core-metaprogramming.adoc
@@ -150,7 +150,45 @@ performance.
 `methodMissing` and `propertyMissing` that deal with static methods and properties can be added via
 the <<core-metaprogramming.adoc#metaprogramming_emc,ExpandoMetaClass>>.
 
-=== GroovyInterceptable (TBD)
+=== GroovyInterceptable
+`GroovyInterceptable` interface is marker interface that extends `GroovyObject` and is used to notify groovy runtime that all methods should be intercepted through the method dispatcher mechanism of groovy runtime.
+
+[source, groovy]
+----
+package groovy.lang;
+
+public interface GroovyInterceptable extends GroovyObject {
+  
+}
+----
+When groovy object implements the `GroovyInterceptable` interface, then its `invokeMethod()` is called for any method's calls. Below you can see a simple example of object of this type.
+
+//TODO Add information about println method. Default groovy object we cannot use with `GroovyInterceptable` interface becaues calling these methods will be intercepted too and we will have `StackOverflowError`.
+
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_object_example,indent=0]
+----
+
+Next piece of code is test which shows that both calls of existed and nonexisted methods will return the same value.
+
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_test,indent=0]
+----
+
+[NOTE]
+We cannot use default groovy methods like as `println` because this methods are injected to all groovy objects so they will be intercepted too.
+
+If we want to intercept all methods call but don't want to implement `GroovyInterceptable` interface we can implement `invokeMethod()` on an object's `MetaClass`. This approach works for both types POGO and POJO. 
+
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy[tags=meta_class_interception,indent=0]
+----
+
+[NOTE]
+Additional information about `MetaClass` you can find in the <<core-metaprogramming.adoc#_metaclasses_tbd,MetaClasses>> topic.
 
 [[categories]]
 === Categories

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/15d5e647/src/spec/test/metaprogramming/InterceptableTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/metaprogramming/InterceptableTest.groovy b/src/spec/test/metaprogramming/InterceptableTest.groovy
new file mode 100644
index 0000000..3950e74
--- /dev/null
+++ b/src/spec/test/metaprogramming/InterceptableTest.groovy
@@ -0,0 +1,20 @@
+package metaprogramming
+
+// tag::groovy_interceptable_test[]
+class InterceptableTest extends GroovyTestCase {
+	void testCheckInterception() {
+		def interception = new Interception()
+		assertEquals interception.definedMethod(), interception.someMethod()
+	}
+}
+// end::groovy_interceptable_test[]
+
+// tag::groovy_interceptable_object_example[]
+class Interception implements GroovyInterceptable {
+	def definedMethod() {}
+	@Override
+	def invokeMethod(String name, Object args) {
+		'invokedMethod'
+	}
+}
+// end::groovy_interceptable_object_example[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/15d5e647/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy b/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy
new file mode 100644
index 0000000..133754c
--- /dev/null
+++ b/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy
@@ -0,0 +1,25 @@
+package metaprogramming
+
+import groovy.xml.Entity
+
+// tag::meta_class_interception[]
+class InterceptionThroughMetaClassTest extends GroovyTestCase {
+    void testPOJOMetaClassInterception() {
+        String invoking = 'ha'
+        invoking.metaClass.invokeMethod = {String name, Object args ->
+            'invoked'
+        }
+        assert invoking.length() == 'invoked'
+        assert invoking.someMethod() == 'invoked'
+    }
+
+    void testPOGOMetaClassInterception() {
+        Entity entity = new Entity('Hello')
+        entity.metaClass.invokeMethod = {String name, Object args ->
+            'invoked'
+        }
+        assert entity.build(new Object()) == 'invoked'
+        assert entity.someMethod() == 'invoked'
+    }
+}
+// end::meta_class_interception[]