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/2d42a54d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/2d42a54d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/2d42a54d

Branch: refs/heads/master
Commit: 2d42a54df73b6ca0410d10b1ac5fdb60fe23edfd
Parents: 16b4221
Author: Maksym Stavytskyi <stavyts...@gmail.com>
Authored: Mon Mar 30 01:53:18 2015 +0300
Committer: pascalschumacher <pascalschumac...@gmx.net>
Committed: Sun May 3 18:35:30 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/2d42a54d/src/spec/doc/core-metaprogramming.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-metaprogramming.adoc 
b/src/spec/doc/core-metaprogramming.adoc
index 68e4e33..81d1c04 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/2d42a54d/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/2d42a54d/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[]

Reply via email to