You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2017/04/25 22:57:44 UTC

[05/20] groovy-user-site git commit: initial version

http://git-wip-us.apache.org/repos/asf/groovy-user-site/blob/33e32ad0/site/src/site/releasenotes/groovy-1.6.adoc
----------------------------------------------------------------------
diff --git a/site/src/site/releasenotes/groovy-1.6.adoc b/site/src/site/releasenotes/groovy-1.6.adoc
new file mode 100644
index 0000000..cf4e2c1
--- /dev/null
+++ b/site/src/site/releasenotes/groovy-1.6.adoc
@@ -0,0 +1,1436 @@
+== Overview of Groovy 1.6
+
+As we shall see in this article, the main highlights of this Groovy 1.6
+release are:
+
+* *Greater compile-time and runtime performance improvements*
+* Multiple assignments
+* Optional return in�`if`/`else`�and�`try`/`catch`�blocks
+* Java 5 annotation definition
+* *AST transformations*�and all the provided transformation annotations
+like`@Singleton`,�`@Lazy`,�`@Immutable`,�`@Delegate`�and friends
+* The Grape module and dependency system and its�`@Grab`�transformation
+* Various Swing builder improvements, thanks to the Swing
+/�link:http://griffon-framework.org/[Griffon]�team, as well as several Swing
+console improvements
+* The integration of�*JMX builder*
+* Various�*metaprogramming improvements*, like the EMC DSL, per-instance
+metaclasses even for POJOs, and runtime mixins
+* *JSR-223*�scripting engine built-in
+* Out-of-the-box�*OSGi readiness*
+
+All those improvements and new features serve one goal:�*helping
+developers be more productive and more agile*, by:
+
+* Focusing more on the task at hand than on boiler-plate technical code
+* Leveraging existing Enterprise APIs rather than reinventing the wheel
+* Improving the overal performance and quality of the language
+* Enabling developers to customize the language at will to derive their
+own Domain-Specific Languages
+
+But beyond all these important aspects,�*Groovy is not just a language,
+it\u2019s a whole ecosystem*.
+
+The improvements in Groovy\u2019s generated bytecode information helps
+capable tools coverage
+like�link:http://cobertura.github.io/cobertura/[Cobertura]�and
+its Groovy support, or pave the way for new utilities
+like�link:http://codenarc.sourceforge.net/[CodeNarc]�for static code analysis
+for Groovy.
+
+The malleability of the syntax of the language and its metaprogramming
+capabilities give birth to advanced testing tools such as
+the link:http://easyb.org/[Easyb]�Behavior-Driven-Development project,
+the�link:http://code.google.com/p/gmock/[GMock]�mocking library or
+the�link:http://code.google.com/p/spock/[Spock]�testing and specification
+framework.
+
+Again, Groovy\u2019s flexibility and expressivity and its scripting
+capabilities open the doors to advanced build scripting or
+infrastructure systems for your continuous integration practices and
+project build solutions, such
+as�link:https://gant.github.io/[Gant]�and�link:http://www.gradle.org/[Gradle].
+
+At the tooling level, Groovy also progresses, for instance with
+its�`groovydoc`�Ant task to let you generate proper JavaDoc covering,
+documenting and interlinking both your Groovy and Java source files for
+your Groovy/Java mixed projects.
+
+And at the same time, IDE makers improve their support for Groovy, by
+giving users powerful weapons such as cross-language code refactoring,
+profound understanding of dynamic language idioms, code completion, and
+more, to make developers productive when using Groovy in their projects.
+
+Now, armed with this knowledge of the Groovy world, it\u2019s time to dive
+into the novelties of Groovy 1.6!
+
+[[Groovy16releasenotes-Performanceimprovements]]
+== Performance improvements
+
+A lot of care has been taken to improve both the compile-time and
+runtime performance of Groovy, compared to previous releases.
+
+The�*compiler is 3 to 5 times faster*�than in previous releases. This
+improvement has also been backported in the 1.5.x branch, so that both
+the old maintenance branch and the current stable branch benefit from
+this work. Thanks to class lookup caches, the bigger the project, the
+faster the compilation will be.
+
+However, the most noticeable changes will be in the general runtime
+performance improvements of Groovy. We used several benchmarks from
+the�link:http://shootout.alioth.debian.org/[Great Language Shootout]�to
+measure our progress. On those we selected, compared to the old Groovy
+1.5.x line, the*performance improvements ranged from 150% to 460%*.
+Micro-benchmarks obviously rarely reflect the kind of code you have in
+your own projects, but the overal performance of your projects should
+improve significantly.
+
+[[Groovy16releasenotes-Multipleassignments]]
+== Multiple assignments
+
+In Groovy 1.6, there is only one syntax addition for being able to
+define and assign several variables at once:
+
+[source,groovy]
+-------------------
+def (a, b) = [1, 2]
+
+assert a == 1
+assert b == 2
+-------------------
+
+A more meaninful example may be methods returning longitute and latitude
+coordinates. If these coordinates are represented as a list of two
+elements, you can easily get back to each element as follows:
+
+[source,groovy]
+---------------------------------------------------------------------
+def geocode(String location) {
+    // implementation returns [48.824068, 2.531733] for Paris, France
+}
+
+def (lat, long) = geocode("Paris, France")
+
+assert lat == 48.824068
+assert long == 2.531733
+---------------------------------------------------------------------
+
+And you can also define the types of the variables in one shot as
+follows:
+
+[source,groovy]
+-------------------------------------
+def (int i, String s) = [1, 'Groovy']
+
+
+assert i == 1
+assert s == 'Groovy'
+-------------------------------------
+
+For the assignment (with prior definition of the variables), just omit
+the�`def`�keyword:
+
+[source,groovy]
+------------------------------------------------------
+def firstname, lastname
+
+
+(firstname, lastname) = "Guillaume Laforge".tokenize()
+
+
+assert firstname == "Guillaume"
+assert lastname == "Laforge"
+------------------------------------------------------
+
+If the list on the right-hand side contains more elements than the
+number of variables on the left-hand side, only the first elements will
+be assigned in order into the variables. Also, when there are less
+elements than variables, the extra variables will be assigned null.
+
+So for the case with more variables than list elements, here,�`c`�will
+be�`null`:
+
+[source,groovy]
+------------------------
+def elements = [1, 2]
+def (a, b, c) = elements
+
+
+assert a == 1
+assert b == 2
+assert c == null
+------------------------
+
+Whereas in the case where there are more list elements than variables,
+we\u2019ll get the following expectations:
+
+[source,groovy]
+---------------------------
+def elements = [1, 2, 3, 4]
+def (a, b, c) = elements
+
+
+assert a == 1
+assert b == 2
+assert c == 3
+---------------------------
+
+For the curious minds, supporting multiple assignments also means we can
+do the standard school swap case in one line:
+
+[source,groovy]
+-----------------------------
+// given those two variables
+def a = 1, b = 2
+
+
+// swap variables with a list
+(a, b) = [b, a]
+
+
+assert a == 2
+assert b == 1
+-----------------------------
+
+[[Groovy16releasenotes-Annotationdefinition]]
+== Annotation definition
+
+Actually, when I said that multiple assignments were the sole syntax
+addition, it\u2019s not entirely true. Groovy supported the syntax for
+annotation definition even in Groovy 1.5, but we had not implemented the
+feature completely. Fortunately, this is now fixed, and it wraps up all
+the Java 5 features supported by Groovy, such as�*static
+imports*,�*generics*,�*annotations*, and�*enums*, making Groovy
+the�*sole alternative dynamic language for the JVM supporting all those
+Java 5 features*, which is critical for a seamless Java integration
+story, and for the usage in Enterprise frameworks relying on
+annotations, generics and more, like JPA, EJB3, Spring, TestNG, etc.
+
+[[Groovy16releasenotes-Optionalreturnforifelseandtrycatchfinallyblocks]]
+== Optional return for if/else and try/catch/finally blocks
+
+It is now possible for�`if/else`�and�`try/catch/finally`�blocks to
+return a value when they are the last expression in a method or a
+closure. No need to explicitly use the�`return`�keyword inside these
+constructs, as long as they are the latest expression in the block of
+code.
+
+As an example, the following method will return�`1`, although
+the�`return`�keyword was omitted.
+
+[source,groovy]
+----------------------
+def method() {
+    if (true) 1 else 0
+}
+
+
+assert method() == 1
+----------------------
+
+For�`try/catch/finally`�blocks, the last expression evaluated is the one
+being returned. If an exception is thrown in the�`try`�block, the last
+expression in the�`catch`�block is returned instead. Note
+that�`finally`�blocks don\u2019t return any value.
+
+[source,groovy]
+--------------------------------------------
+def method(bool) {
+    try {
+        if (bool) throw new Exception("foo")
+        1
+    } catch(e) {
+        2
+    } finally {
+        3
+    }
+}
+
+
+assert method(false) == 1
+assert method(true) == 2
+--------------------------------------------
+
+[[Groovy16releasenotes-ASTTransformations]]
+== AST Transformations
+
+Although at times, it may sound like a good idea to extend the syntax of
+Groovy to implement new features (like this is the case for instance for
+multiple assignments), most of the time, we can\u2019t just add a new keyword
+to the grammar, or create some new syntax construct to represent a new
+concept. However, with the idea of AST (Abstract Syntax Tree)
+Transformations, we are able to tackle new and innovative ideas without
+necessary grammar changes.
+
+When the Groovy compiler compiles Groovy scripts and classes, at some
+point in the process, the source code will end up being represented in
+memory in the form of a Concrete Syntax Tree, then transformed into an
+Abstract Syntax Tree. The purpose of AST Transformations is to let
+developers hook into the compilation process to be able to modify the
+AST before it is turned into bytecode that will be run by the JVM.
+
+*AST Transformations provides Groovy with improved compile-time
+metaprogramming capabilities*�allowing powerful flexibility at the
+language level, without a runtime performance penalty.
+
+There are two kinds of transformations: global and local
+transformations.
+
+* Global transformations are applied to by the compiler on the code
+being compiled, wherever the transformation apply. A JAR added to the
+classpath of the compiler should contain a service locator file
+at�`META-INF/services/org.codehaus.groovy.transform.ASTTransformation`�with
+a line with the name of the transformation class. The transformation
+class must have a no-args constructor and implement
+the�`org.codehaus.groovy.transform.ASTTransformation`interface. It will
+be run against every source in the compilation, so be sure to not create
+transformations which scan all the AST in an expansive and
+time-consuming manner, to keep the compiler fast.
+* Local transformations are transformations applied locally by
+annotating code elements you want to transform. For this, we reuse the
+annotation notation, and those annotations should
+implement�`org.codehaus.groovy.transform.ASTTransformation`. The
+compiler will discover them and apply the transformation on these code
+elements.
+
+Groovy 1.6 provides several local transformation annotations, in the
+Groovy Swing Builder for data binding (`@Bindable`�and�`@Vetoable`), in
+the Grape module system for adding script library dependencies
+(`@Grab`), or as general language features without requiring any syntax
+change to support them
+(`@Singleton`,�`@Immutable`,�`@Delegate`,�`@Lazy`,�`@Newify`,�`@Category`,�`@Mixin`�and�`@PackageScope`).
+Let\u2019s have a look at some of these transformations
+(`@Bindable`�and�`@Vetoable`�will be covered in the section related to
+the Swing enhancements, and�`@Grab`�in the section about Grape).
+
+[[Groovy16releasenotes-Singleton]]
+=== @Singleton
+
+Whether the singleton is pattern or an anti-pattern, there are still
+some cases where we need to create singletons. We\u2019re used to create a
+private constructor, a�`getInstance()`�method for a static field or even
+an initialized�`public static final`�field. So instead of writing code
+like this in Java:
+
+[source,groovy]
+---------------------------------------------
+public class T {
+    public static final T instance = new T();
+    private T() {}
+}
+---------------------------------------------
+
+You just need to annotate your type with the�`@Singleton`�annotation:
+
+[source,groovy]
+---------------------
+@Singleton class T {}
+---------------------
+
+The singleton instance can then simply be accessed
+with�`T.instance`�(direct public field access).
+
+You can also have the lazy loading approach with an additional
+annotation parameter:
+
+[source,groovy]
+----------------------------------
+@Singleton(lazy = true) class T {}
+----------------------------------
+
+Would become more or less equivalent to this Groovy class:
+
+[source,groovy]
+---------------------------------------
+class T {
+    private static volatile T instance
+    private T() {}
+    static T getInstance () {
+        if (instance) {
+            instance
+        } else {
+            synchronized(T) {
+                if (instance) {
+                    instance
+                } else {
+                    instance = new T ()
+                }
+            }
+        }
+    }
+}
+---------------------------------------
+
+Lazy or not, once again, to access the instance, simply
+do�`T.instance`�(property access, shorcut for�`T.getInstance()`).
+
+[[Groovy16releasenotes-Immutable]]
+=== @Immutable
+
+Immutable objects are ones which don\u2019t change after initial creation.
+Such objects are frequently desirable because they are simple and can be
+safely shared even in multi-threading contexts. This makes them great
+for functional and concurrent scenarios. The rules for creating such
+objects are well-known:
+
+* No mutators (methods that modify internal state)
+* Class must be final
+* Fields must be private and final
+* Defensive copying of mutable components
+* `equals()`,�`hashCode()`�and�`toString()`�must be implemented in terms
+of the fields if you want to compare your objects or use them as keys in
+e.g. maps
+
+Instead of writing a very long Java or Groovy class mimicking this
+immutability behavior, Groovy lets you just write an immutable class as
+follow:
+�
+[source,groovy]
+------------------------------------------------------------------
+@Immutable final class Coordinates {
+    Double latitude, longitude
+}
+
+
+def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)
+def c2 = new Coordinates(48.824068, 2.531733)
+
+
+assert c1 == c2
+------------------------------------------------------------------
+
+All the boiler-plate code is generated at compile-time for you! The
+example shows that to instantiate such immutable coordinates, you can
+use one of the two constructors created by the transformation, one
+taking a map whose keys are the properties to set to the values
+associated with those keys, and the other taking the values of the
+properties as parameters. The�`assert`�also shows that�`equals()`�was
+implemented and allows us to properly compare such immutable objects.
+
+You can have a look at
+the�link:http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/Immutable.html[details of the implementation]�of this transformation. For the record, the Groovy
+example above using the`@Immutable`�transformation is over 50 lines of
+equivalent Java code.
+
+[[Groovy16releasenotes-Lazy]]
+=== @Lazy
+
+Another transformation is�`@Lazy`. Sometimes, you want to handle the
+initialization of a field of your clas lazily, so that its value is
+computed only on first use, often because it may be time-consuming or
+memory-expensive to create. The usual approach is to customize the
+getter of said field, so that it takes care of the initialization when
+the getter is called the first time. But in Groovy 1.6, you can now use
+the�`@Lazy`�annotation for that purpose:
+
+[source,groovy]
+---------------------------------------
+class Person {
+    @Lazy pets = ['Cat', 'Dog', 'Bird']
+}
+
+
+def p = new Person()
+assert !(p.dump().contains('Cat'))
+
+assert p.pets.size() == 3
+assert p.dump().contains('Cat')
+---------------------------------------
+
+In the case of complex computation for initializing the field, you may
+need to call some method for doing the work, instead of a value like our
+pets list. This is then possible to have the lazy evaluation being done
+by a closure call, as the following example shows:
+
+[source,groovy]
+----------------------------------------------------------
+class Person {
+    @Lazy List pets = { /* complex computation here */ }()
+}
+----------------------------------------------------------
+
+There is also an option for leveraging Soft references for garbage
+collection friendliness for expensive data structures that may be
+contained by such lazy fields:
+
+[source,groovy]
+---------------------------------------------------------
+class Person {
+    @Lazy(soft = true) List pets = ['Cat', 'Dog', 'Bird']
+}
+
+
+def p = new Person()
+assert p.pets.contains('Cat')
+---------------------------------------------------------
+
+The internal field created by the compiler for�`pets`�will actually be a
+Soft reference, but accessing�`p.pets`�directly will return the value
+(ie. the list of pets) held by that reference, making the use of the
+soft reference transparent to the user of that class.
+
+[[Groovy16releasenotes-Delegate]]
+=== @Delegate
+
+Java doesn\u2019t provide any built-in delegation mechanism, and so far
+Groovy didn\u2019t either. But with the�`@Delegate`�transformation, a class
+field or property can be annotated and become an object to which method
+calls are delegated. In the following example, an�`Event`�class has a
+date delegate, and the compiler will delegate all of�`Date`\u2019s methods
+invoked on the�`Event`�class to the�`Date`�delegate. As shown in the
+latest�`assert`, the�`Event`�class has got a�`before(Date)`�method, and
+all of�`Date`\u2019s methods.
+
+[source,groovy]
+--------------------------------------------------------------
+import java.text.SimpleDateFormat
+
+
+class Event {
+    @Delegate Date when
+    String title, url
+}
+
+
+def df = new SimpleDateFormat("yyyy/MM/dd")
+
+
+def gr8conf = new Event(title: "GR8 Conference",
+                          url: "http://www.gr8conf.org",
+                         when: df.parse("2009/05/18"))
+def javaOne = new Event(title: "JavaOne",
+                          url: "http://java.sun.com/javaone/",
+                         when: df.parse("2009/06/02"))
+
+assert gr8conf.before(javaOne.when)
+--------------------------------------------------------------
+
+The Groovy compiler adds all of�`Date`\u2019s methods to the�`Event`�class,
+and those methods simply delegate the call to the�`Date`�field. If the
+delegate is not a final class, it is even possible to make
+the�`Event`�class a subclass of�`Date`�simply by extending�`Date`, as
+shown below. No need to implement the delegation ourselves by adding
+each and every�`Date`�methods to our�`Event`�class, since the compiler
+is friendly-enough with us to do the job itself.
+
+[source,groovy]
+--------------------------
+class Event extends Date {
+    @Delegate Date when
+    String title, url
+}
+--------------------------
+
+In the case you are delegating to an interface, however, you don\u2019t even
+need to explictely say you implement the interface of the delegate.
+The�`@Delegate`�transformation will take care of this and implement that
+interface. So the instances of your class will automatically
+be�`instanceof`�the delegate\u2019s interface.
+
+[source,groovy]
+-----------------------------------------------------
+import java.util.concurrent.locks.*
+
+
+class LockableList {
+    @Delegate private List list = []
+    @Delegate private Lock lock = new ReentrantLock()
+}
+
+
+def list = new LockableList()
+
+
+list.lock()
+try {
+    list << 'Groovy'
+    list << 'Grails'
+    list << 'Griffon'
+} finally {
+    list.unlock()
+}
+
+
+assert list.size() == 3
+assert list instanceof Lock
+assert list instanceof List
+-----------------------------------------------------
+
+In this example, our�`LockableList`�is now a composite of a list and a
+lock and is�`instanceof`�of�`List`�and�`Lock`. However, if you didn\u2019t
+intend your class to be implementing these interfaces, you would still
+be able to do so by specifying a parameter on the annotation:
+
+[source,groovy]
+----------------------------------------------------
+@Delegate(interfaces = false) private List list = []
+----------------------------------------------------
+
+[[Groovy16releasenotes-Newify]]
+=== @Newify
+
+The�`@Newify`�transformation proposes two new ways of instantiating
+classes. The first one is providing Ruby like approach to creating
+instances with a�`new()`�class method:
+
+[source,groovy]
+--------------------------------
+@Newify rubyLikeNew() {
+    assert Integer.new(42) == 42
+}
+
+
+rubyLikeNew()
+--------------------------------
+
+But it is also possible to follow the Python approach with omitting
+the�`new`�keyword. Imagine the following tree creation:
+
+[source,groovy]
+-----------------------------------------------------------------
+class Tree {
+    def elements
+    Tree(Object... elements) { this.elements = elements as List }
+}
+
+
+class Leaf {
+    def value
+    Leaf(value) { this.value = value }
+}
+
+
+def buildTree() {
+    new Tree(new Tree(new Leaf(1), new Leaf(2)), new Leaf(3))
+}
+
+
+buildTree()
+-----------------------------------------------------------------
+
+The creation of the tree is not very readable because of all
+those�`new`�keywords spread across the line. The Ruby approach wouldn\u2019t
+be more readable, since a�`new()`�method call for creating each element
+is needed. But by using�`@Newify`, we can improve our tree building
+slightly to make it easier on the eye:
+
+[source,groovy]
+-----------------------------------------
+@Newify([Tree, Leaf]) buildTree() {
+    Tree(Tree(Leaf(1), Leaf(2)), Leaf(3))
+}
+-----------------------------------------
+
+You\u2019ll also notice that we just allowed�`Tree`�and�`Leaf`�to
+be�_newified_. By default, under the scope which is annotated, all
+instantiations are_newified_, but you can limit the reach by specifying
+the classes you\u2019re interested in. Also, note that for our example,
+perhaps a Groovy builder may have been more appropriate, since its
+purpose is to indeed create any kind of hierarchical / tree strucutre.
+
+If we take another look at our coordinates example from a few sections
+earlier, using both�`@Immutable`�and�`@Newify`�can be interesting for
+creating a path with a concise but type-safe manner:
+
+[source,groovy]
+-----------------------------------------
+@Immutable final class Coordinates {
+    Double latitude, longitude
+}
+
+
+@Immutable final class Path {
+    Coordinates[] coordinates
+}
+
+
+@Newify([Coordinates, Path])
+def build() {
+    Path(
+        Coordinates(48.824068, 2.531733),
+        Coordinates(48.857840, 2.347212),
+        Coordinates(48.858429, 2.342622)
+    )
+}
+
+
+assert build().coordinates.size() == 3
+-----------------------------------------
+
+A closing remark here: since a�`Path(Coordinates[] coordinates)`�was
+generated, we can use that constructor in a�_varargs way_�in Groovy,
+just as if it had been defined as�`Path(Coordinates... coordinates)`.
+
+[[Groovy16releasenotes-CategoryandMixin]]
+=== @Category and @Mixin
+
+If you\u2019ve been using Groovy for a while, you\u2019re certainly familiar with
+the concept of Categories. It\u2019s a mechanism to extend existing types
+(even final classes from the JDK or third-party libraries), to add new
+methods to them. This is also a technique which can be used when writing
+Domain-Specific Languages. Let\u2019s consider the example below:
+
+[source,groovy]
+--------------------------------------------
+final class Distance {
+    def number
+    String toString() { "${number}m" }
+}
+
+
+class NumberCategory {
+    static Distance getMeters(Number self) {
+        new Distance(number: self)
+    }
+}
+
+
+use(NumberCategory) {
+    def dist = 300.meters
+
+
+    assert dist instanceof Distance
+    assert dist.toString() == "300m"
+}
+--------------------------------------------
+
+We have a simplistic and fictive�`Distance`�class which may have been
+provided by a third-party, who had the bad idea of making the
+class`final`�so that nobody could ever extend it in any way. But thanks
+to a Groovy Category, we are able to decorate the�`Distance`�type with
+additional methods. Here, we\u2019re going to add a�`getMeters()`�method to
+numbers, by actually decorating the�`Number`�type. By adding a getter to
+a number, you\u2019re able to reference it using the nice property syntax of
+Groovy. So instead of writing�`300.getMeters()`, you\u2019re able to
+write�`300.meters`.
+
+The downside of this category system and notation is that to add
+instance methods to other types, you have to create�`static`�methods,
+and furthermore, there\u2019s a first argument which represents the instance
+of the type we\u2019re working on. The other arguments are the normal
+arguments the method will take as parameters. So it may be a bit less
+intuitive than a normal method definition we would have added
+to�`Distance`, should we have had access to its source code for
+enhancing it. Here comes the�`@Category`�annotation, which transforms a
+class with instance methods into a Groovy category:
+
+[source,groovy]
+----------------------------------
+@Category(Number)
+class NumberCategory {
+    Distance getMeters() {
+        new Distance(number: this)
+    }
+}
+----------------------------------
+
+No need for declaring the methods�`static`, and the�`this`�you use here
+is actually the number on which the category will apply, it\u2019s not the
+real�`this`�of the category instance should we create one. Then to use
+the category, you can continue to use the�`use(Category) {}`construct.
+What you\u2019ll notice however is that these kind of categories only apply
+to one single type at a time, unlike classical categories which can be
+applied to any number of types.
+
+Now, pair�`@Category`�extensions to the�`@Mixin`�transformation, and you
+can mix in various behavior in a class, with an approach similar to
+multiple inheritance:
+
+[source,groovy]
+-------------------------------------------------
+@Category(Vehicle) class FlyingAbility {
+    def fly() { "I'm the ${name} and I fly!" }
+}
+
+
+@Category(Vehicle) class DivingAbility {
+    def dive() { "I'm the ${name} and I dive!" }
+}
+
+
+interface Vehicle {
+    String getName()
+}
+
+
+@Mixin(DivingAbility)
+class Submarine implements Vehicle {
+    String getName() { "Yellow Submarine" }
+}
+
+
+@Mixin(FlyingAbility)
+class Plane implements Vehicle {
+    String getName() { "Concorde" }
+}
+
+
+@Mixin([DivingAbility, FlyingAbility])
+class JamesBondVehicle implements Vehicle {
+    String getName() { "James Bond's vehicle" }
+}
+
+
+assert new Plane().fly() ==
+       "I'm the Concorde and I fly!"
+assert new Submarine().dive() ==
+       "I'm the Yellow Submarine and I dive!"
+
+
+assert new JamesBondVehicle().fly() ==
+       "I'm the James Bond's vehicle and I fly!"
+assert new JamesBondVehicle().dive() ==
+       "I'm the James Bond's vehicle and I dive!"
+-------------------------------------------------
+
+You don\u2019t inherit from various interfaces and inject the same behavior
+in each subclass, instead you mixin the categories into your class.
+Here, our marvelous James Bond vehicle gets the flying and diving
+capabilities through mixins.
+
+An important point to make here is that unlike�`@Delegate`�which
+can�_inject_�interfaces into the class in which the delegate is
+declared,`@Mixin`�just does runtime mixing \u2014 as we shall see in the
+metaprogramming enhancements further down in this article.
+
+[[Groovy16releasenotes-PackageScope]]
+=== @PackageScope
+
+Groovy\u2019s convention for properties is that any�_field_�without any
+visibility modifier is exposed as a property, with a getter and a setter
+transparently generated for you. For instance, this�`Person`�class
+exposes a getter�`getName()`�and a setter�`setName()`�for a
+private�`name`�field:
+
+[source,groovy]
+---------------
+class Person {
+    String name
+}
+---------------
+
+Which is equivalent to this Java class:
+
+[source,groovy]
+---------------------------------------------------
+public class Person {
+    private String name;
+    public String getName() { return name; }
+    public void setName(name) { this.name = name; }
+}
+---------------------------------------------------
+
+That said, this approach has one drawback in that you don\u2019t have the
+possibility to define a field with package-scope visibility. To be able
+to expose a field with package-scope visibility, you can now annotate
+your field with the�`@PackageScope`�annotation.
+
+[[Groovy16releasenotes-GrapetheGroovyAdaptableAdvancedPackagingEngine]]
+== Grape, the Groovy Adaptable / Advanced Packaging Engine
+
+To continue our overview of the AST transformations, we\u2019ll now learn
+more about Grape, a mechanism to add and leverage dependencies in your
+Groovy scripts. Groovy scripts can require certain libraries: by
+explicitly saying so in your script with the�*@Grab*�transformation or
+with the�*Grape.grab()*�method call, the runtime will find the needed
+JARs for you. With Grape, you can easily distribute scripts without
+their dependencies, and have them downloaded on first use of your script
+and cached. Under the hood, Grape uses Ivy and Maven repositories
+containing the libraries you may need in your scripts.
+
+Imagine you want to get the links of all the PDF documents referenced by
+the Java 5 documentation. You want to parse the HTML page as if it were
+an XML-compliant document (which it is not) with the Groovy�`XmlParser`,
+so you can use the TagSoup SAX-compliant parser which transforms HTML
+into well-formed valid XML. You don\u2019t even have to mess up with your
+classpath when running your script, just_grab_�the TagSoup library
+through Grape:
+
+[source,groovy]
+------------------------------------------------------------------------
+import org.ccil.cowan.tagsoup.Parser
+
+
+// find the PDF links in the Java 1.5.0 documentation
+@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
+def getHtml() {
+    def tagsoupParser = new Parser()
+    def parser = new XmlParser(tagsoupParser)
+    parser.parse("http://java.sun.com/j2se/1.5.0/download-pdf.html")
+}
+
+html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it }
+------------------------------------------------------------------------
+
+For the pleasure of giving another example: let\u2019s use
+the�link:http://eclipse.org/jetty/[Jetty servlet container]�to
+expose�link:{DOCS_BASEURL}/html/documentation/template-engines.html[Groovy templates]�in
+a few lines of code:
+
+[source,groovy]
+--------------------------------------------------------------------------------
+import org.mortbay.jetty.Server
+import org.mortbay.jetty.servlet.*
+import groovy.servlet.*
+
+
+@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
+def runServer(duration) {
+    def server = new Server(8080)
+    def context = new Context(server, "/", Context.SESSIONS);
+    context.resourceBase = "."
+    context.addServlet(TemplateServlet, "*.gsp")
+    server.start()
+    sleep duration
+    server.stop()
+}
+
+
+runServer(10000)
+--------------------------------------------------------------------------------
+
+Grape will download Jetty and its dependencies on first launch of this
+script, and cache them. We\u2019re creating a new Jetty�`Server`�on port
+8080, then expose Groovy\u2019s�`TemplateServlet`�at the root of the context
+\u2014 Groovy comes with its own powerful template engine mechanism. We start
+the server and let it run for a certain duration. Each time someone will
+hit�+http://localhost:8080/somepage.gsp+, it will display
+the�`somepage.gsp`�template to the user \u2014 those template pages should be
+situated in the same directory as this server script.
+
+Grape can also be used as a method call instead of as an annotation. You
+can also install, list, resolve dependencies from the command-line using
+the�`grape`�command. For�link:../grape.html[more information on Grape], please refer to the documentation.
+
+[[Groovy16releasenotes-Swingbuilderimprovements]]
+== Swing builder improvements
+
+To wrap up our overview of AST transformations, let\u2019s finish by speaking
+about two transformations very useful to Swing
+developers:`@Bindable`�and�`@Vetoable`. When creating Swing UIs, you\u2019re
+often interested in monitoring the changes of value of certain UI
+elements. For this purpose, the usual approach is to use
+JavaBeans�`PropertyChangeListener`s to be notified when the value of a
+class field changes. You then end up writing this very common
+boiler-plate code in your Java beans:
+
+[source,groovy]
+------------------------------------------------------------------------
+import com.googlecode.openbeans.PropertyChangeSupport;
+import com.googlecode.openbeans.PropertyChangeListener;
+
+
+public class MyBean {
+    private String prop;
+
+
+    PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+
+
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        pcs.add(l);
+    }
+
+
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        pcs.remove(l);
+    }
+
+
+    public String getProp() {
+        return prop;
+    }
+
+
+    public void setProp(String prop) {
+        pcs.firePropertyChanged("prop", this.prop, this.prop = prop);
+    }
+
+}
+------------------------------------------------------------------------
+
+Fortunately, with Groovy and the�`@Bindable`�annotation, this code can
+be greatly simplified:
+
+[source,groovy]
+-------------------------
+class MyBean {
+    @Bindable String prop
+}
+-------------------------
+
+Now pair that with Groovy\u2019s Swing builder new�`bind()`�method, define a
+text field and bind its value to a property of your data model:
+
+[source,groovy]
+--------------------------------------------------------------------
+textField text: bind(source: myBeanInstance, sourceProperty: 'prop')
+--------------------------------------------------------------------
+
+Or even:
+
+[source,groovy]
+--------------------------------------------
+textField text: bind { myBeanInstance.prop }
+--------------------------------------------
+
+The binding also works with simple expressions in the closure, for
+instance something like this is possible too:
+
+[source,groovy]
+--------------------------------------------
+bean location: bind { pos.x + ', ' + pos.y }
+--------------------------------------------
+
+You may also be interested in having a look
+at�link:{DOCS_BASEURL}/html/api/groovy/util/ObservableMap.html[ObservableMap]�and�link:{DOCS_BASEURL}/html/api/groovy/util/ObservableList.html[ObservableList],
+for a similar mechanism on maps and lists.
+
+Along with�`@Bindable`, there\u2019s also a�`@Vetoable`�transformation for
+when you need to be able to veto some property change. Let\u2019s consider
+a�`Trompetist`�class, where the performer\u2019s name is not allowed to
+contain the letter `z':
+
+[source,groovy]
+---------------------------------------------------------------------------------------
+import com.googlecode.openbeans.*
+import groovy.beans.Vetoable
+
+
+class Trumpetist {
+    @Vetoable String name
+}
+
+
+def me = new Trumpetist()
+me.vetoableChange = { PropertyChangeEvent pce ->
+    if (pce.newValue.contains('z'))
+        throw new PropertyVetoException("The letter 'z' is not allowed in a name", pce)
+}
+
+
+me.name = "Louis Armstrong"
+
+
+try {
+    me.name = "Dizzy Gillespie"
+    assert false: "You should not be able to set a name with letter 'z' in it."
+} catch (PropertyVetoException pve) {
+    assert true
+}
+---------------------------------------------------------------------------------------
+
+Looking at a more thorough Swing builder example with binding:
+
+[source,groovy]
+----------------------------------------------------------------------------
+import groovy.swing.SwingBuilder
+import groovy.beans.Bindable
+import static javax.swing.JFrame.EXIT_ON_CLOSE
+
+
+class TextModel {
+    @Bindable String text
+}
+
+
+def textModel = new TextModel()
+
+
+SwingBuilder.build {
+    frame( title: 'Binding Example (Groovy)', size: [240,100], show: true,
+          locationRelativeTo: null, defaultCloseOperation: EXIT_ON_CLOSE ) {
+        gridLayout cols: 1, rows: 2
+        textField id: 'textField'
+        bean textModel, text: bind{ textField.text }
+        label text: bind{ textModel.text }
+    }
+}
+----------------------------------------------------------------------------
+
+Running this script shows up the frame below with a text field and a
+lable below, and the label\u2019s text is bound on the text field\u2019s content.
+
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/bindable-example.png[image]
+
+SwingBuilder has evolved so nicely in the past year that the Groovy
+Swing team decided to launch a new project based on it, and on the
+Grails foundations: project�link:http://griffon-framework.org/[Griffon]�was
+born. Griffon proposes to bring the�_Convention over
+Configuration_�paradigm of Grails, as well as all its project structure,
+plugin system, gant scripting capabilities, etc.
+
+If you are developing Swing rich clients, make sure to have a look
+at�link:http://griffon-framework.org/[Griffon].
+
+[[Groovy16releasenotes-Swingconsoleimprovements]]
+== Swing console improvements
+
+Swinging along the topic of UIs, the Swing console has also evolved:
+
+* The console can be run as an Applet (`groovy.ui.ConsoleApplet`).
+* Beyond syntax highlighting, the editor also supports code indentation.
+* Drag\u2019n droping a Groovy script over the text area will open the file.
+* You can modify the classpath with which the script in the console is
+being run, by adding a new JAR or a directory to the classpath as shown
+in the screenshot below.
++
++
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-add-jar.png[image]
++
+* A couple options have been added to the view menu item: for showing
+the script being run in the output area, and for visualizing the
+execution results.
++
++
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-options.png[image]
++
+* When an exception is thrown in your script, the lines of the
+stacktrace relative to your script are clickable, for easy navigation to
+the point where the error occurred.
++
++
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-stack.png[image]
++
+* Also, when your script contains compilation errors, the error messages
+are clickable too.
++
++
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-comp-error.png[image]
++
+
+Back on the visualization of the results in the script output area, a
+fun system was added to let you customize how certain results are
+rendered. When you execute a script returning a map of Jazz musicians,
+you may see something like this in your console:
+
+image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-without-visu.png[image]
+
+What you see here is the usual textual representation of a�`Map`. But,
+what if we enabled custom visualization of certain results? The Swing
+console allows you to do just that. First of all, you have to ensure
+that the visualization option is
+ticked:�`View -> Visualize Script Results`�\u2014 for the record, all
+settings of the Groovy Console are stored and remembered thanks to the
+Preference API. There are a few result visualizations built-in: if the
+script returns a�`java.awt.Image`, a�`javax.swing.Icon`, or
+a�`java.awt.Component`�with no parent, the object is displayed instead
+of its�`toString()`�representation. Otherwise, everything else is still
+just represented as text. Now, create the following Groovy script
+in�`~/.groovy/OutputTransforms.groovy`:
+
+[source,groovy]
+---------------------------------------------------------
+import javax.swing.*
+
+transforms << { result ->
+    if (result instanceof Map) {
+        def table = new JTable(
+            result.collect{ k, v -<
+                [k, v?.inspect()] as Object[]
+            } as Object[][],
+            ['Key', 'Value'] as Object[])
+        table.preferredViewportSize = table.preferredSize
+        return new JScrollPane(table)
+    }
+}
+---------------------------------------------------------
+
+The Groovy Swing console will execute that script on startup, injecting
+a�`transforms`�list in the binding of the script, so that you can add
+your own script results representations. In our case, we transform
+the�`Map`�into a nice-looking Swing�`JTable`. And we\u2019re now able to
+visualize maps in a friendly and attractive fashion, as the screenshot
+below
+shows:image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-with-visu.png[image]
+
+The Swing console is obviously not to be confused with a real full-blown
+IDE, but for daily scripting tasks, the console is a handy tool in your
+toolbox.
+
+[[Groovy16releasenotes-Metaprogrammingenhancements]]
+== Metaprogramming enhancements
+
+What makes Groovy a dynamic language is its Meta-Object Protocol and its
+concept of metaclasses which represent the runtime behavior of your
+classes and instances. In Groovy 1.6, we continue improving this dynamic
+runtime system, bringing several new capabilities into the mix.
+
+[[Groovy16releasenotes-PerinstancemetaclassevenforPOJOs]]
+=== Per instance metaclass even for POJOs
+
+So far, Groovy POGOs (Plain Old Groovy Objects) could have a
+per-instance metaclass, but POJOs could only have one metaclass for all
+instances (ie. a per-class metaclass). This is now not the case anymore,
+as POJOs can have a per-instance metaclass too. Also, setting the
+metaclass property to null will restore the default metaclass.
+
+[[Groovy16releasenotes-ExpandoMetaClassDSL]]
+=== ExpandoMetaClass DSL
+
+Initially developed under the�link:http://grails.org/[Grails]�umbrella and
+integrated back into Groovy 1.5, ExpandoMetaClass is a very handy way
+for changing the runtime behavior of your objects and classes, instead
+of writing full-blow�`MetaClass`�classes. Each time, we want to add /
+change several properties or methods of an existing type, there is too
+much of a repetition of�`Type.metaClass.xxx`. Take for example this
+extract of
+a�link:http://groovy.dzone.com/news/domain-specific-language-unit-[Unit
+manipulation DSL]�dealing with operator overloading:
+
+[source,groovy]
+---------------------------------------------------------------------------------
+Number.metaClass.multiply = { Amount amount -> amount.times(delegate) }
+Number.metaClass.div =      { Amount amount -> amount.inverse().times(delegate) }
+
+
+Amount.metaClass.div =      { Number factor -> delegate.divide(factor) }
+Amount.metaClass.div =      { Amount factor -> delegate.divide(factor) }
+Amount.metaClass.multiply = { Number factor -> delegate.times(factor) }
+Amount.metaClass.power =    { Number factor -> delegate.pow(factor) }
+Amount.metaClass.negative = { -> delegate.opposite() }
+---------------------------------------------------------------------------------
+
+The repetition, here, looks obvious. But with the ExpandoMetaClass DSL,
+we can streamline the code by regrouping the operators per type:
+
+[source,groovy]
+------------------------------------------------------------------
+Number.metaClass {
+    multiply { Amount amount -> amount.times(delegate) }
+    div      { Amount amount -> amount.inverse().times(delegate) }
+}
+
+
+Amount.metaClass {
+    div <<   { Number factor -> delegate.divide(factor) }
+    div <<   { Amount factor -> delegate.divide(factor) }
+    multiply { Number factor -> delegate.times(factor) }
+    power    { Number factor -> delegate.pow(factor) }
+    negative { -> delegate.opposite() }
+}
+------------------------------------------------------------------
+
+A�`metaClass()`�method takes a closure as single argument, containing
+the various definitions of the methods and properties, instead of
+repeating the�`Type.metaClass`�on each line. When there is just one
+method of a given name, use the pattern�`methodName { /* closure */ }`,
+but when there are several, you should use the append operator and
+follow the patten�`methodName << { /* closure */ }`. Static methods can
+also be added through this mechanism, so instead of the classical
+approach:
+
+[source,groovy]
+---------------------------------------------------------
+// add a fqn() method to Class to get the fully
+// qualified name of the class (ie. simply Class#getName)
+Class.metaClass.static.fqn = { delegate.name }
+
+
+assert String.fqn() == "java.lang.String"
+---------------------------------------------------------
+
+You can now do:
+
+[source,groovy]
+-----------------------------
+Class.metaClass {
+    'static' {
+        fqn { delegate.name }
+    }
+}
+-----------------------------
+
+Note here that you have to quote the�`static`�keyword, to avoid this
+construct to look like a static initializer. For one off method
+addition, the classical approach is obviously more concise, but when you
+have several methods to add, the EMC DSL makes sense.
+
+The usual approach for adding properties to existing classes through
+ExpandoMetaClass is to add a getter and a setter as methods. For
+instance, say you want to add a method that counts the number of words
+in a text file, you could try this:
+
+[source,groovy]
+------------------------------------
+File.metaClass.getWordCount = {
+    delegate.text.split(/\w/).size()
+}
+
+
+new File('myFile.txt').wordCount
+------------------------------------
+
+When there is some logic inside the getter, this is certainly the best
+approach, but when you just want to have new properties holding simple
+values, through the ExpandoMetaClass DSL, it is possible to define them.
+In the following example, a�`lastAccessed`�property is added to
+a�`Car`�class \u2014 each instance will have its property. Whenever a method
+is called on that car, this property is updated with a newer timestamp.
+
+[source,groovy]
+------------------------------------------------------------------------
+class Car {
+    void turnOn() {}
+    void drive() {}
+    void turnOff() {}
+}
+
+
+Car.metaClass {
+    lastAccessed = null
+    invokeMethod = { String name, args ->
+        def metaMethod = delegate.metaClass.getMetaMethod(name, args)
+        if (metaMethod) {
+            delegate.lastAccessed = new Date()
+            metaMethod.doMethodInvoke(delegate, args)
+        } else {
+            throw new MissingMethodException(name, delegate.class, args)
+        }
+    }
+}
+
+
+
+def car = new Car()
+println "Last accessed: ${car.lastAccessed ?: 'Never'}"
+
+
+car.turnOn()
+println "Last accessed: ${car.lastAccessed ?: 'Never'}"
+
+
+car.drive()
+sleep 1000
+println "Last accessed: ${car.lastAccessed ?: 'Never'}"
+
+
+sleep 1000
+car.turnOff()
+println "Last accessed: ${car.lastAccessed ?: 'Never'}"
+------------------------------------------------------------------------
+
+In our example, in the DSL, we access that property through
+the�`delegate`�of the closure,
+with�`delegate.lastAccessed = new Date()`. And we intercept any method
+call thanks to�`invokeMethod()`, delegating to the original method for
+the call, and throwing an exception in case the method doesn\u2019t exist.
+Later on, you can see by executing this script that�`lastAccessed`�is
+updated as soon as we call a method on our instance.
+
+[[Groovy16releasenotes-Runtimemixins]]
+=== Runtime mixins
+
+Last metaprogramming feature we\u2019ll cover today: runtime
+mixins.�`@Mixin`�allowed you to mixin new behavior to classes you owned
+and were designing. But you could not mixin anything to types you didn\u2019t
+own. Runtime mixins propose to fill that gap by letting you add a mixin
+on any type at runtime. If we think again about our example of vehicles
+with some mixed-in capabilities, if we didn\u2019t�_own_�James Bond\u2019s vehicle
+and give it some diving ability, we could use this mechanism:
+
+[source,groovy]
+---------------------------------------------------
+// provided by a third-party
+interface Vehicle {
+    String getName()
+}
+
+
+// provided by a third-party
+class JamesBondVehicle implements Vehicle {
+    String getName() { "James Bond's vehicle" }
+}
+
+
+JamesBondVehicle.mixin DivingAbility, FlyingAbility
+
+
+assert new JamesBondVehicle().fly() ==
+       "I'm the James Bond's vehicle and I fly!"
+assert new JamesBondVehicle().dive() ==
+       "I'm the James Bond's vehicle and I dive!"
+---------------------------------------------------
+
+One or more mixins can be passed as argument to the
+static�`mixin()`�method added by Groovy on�`Class`.
+
+[[Groovy16releasenotes-JSR-223GroovyScriptingEngine]]
+== JSR-223 Groovy Scripting Engine
+
+Before Groovy 1.6, if you wanted to integrate Groovy in your Java
+projects through JSR-223 /�`javax.script.*`, you had to download a
+Groovy script engine implementation from java.net, and put the JAR in
+your classpath. This additional step wasn\u2019t very developer friendly,
+requiring some additional work \u2014 the JAR wasn\u2019t even provided in the
+Groovy distribution. Thankfully, 1.6 comes with an implementation of
+the�`javax.script.*`�APIs.
+
+Below, you\u2019ll find an example evaluating Groovy expressions (the code is
+in Groovy, but it\u2019s straightforward to convert it back to Java):
+
+[source,groovy]
+----------------------------------------------
+import javax.script.*
+
+
+def manager = new ScriptEngineManager()
+def engine = manager.getEngineByName("groovy")
+
+
+assert engine.evaluate("2 + 3") == 5
+----------------------------------------------
+
+Please note that the�`javax.script.*`�APIs are available only on Java 6.
+
+[[Groovy16releasenotes-JMXBuilder]]
+== JMX Builder
+
+Originiating as an�link:http://code.google.com/p/groovy-jmx-builder/[external
+Open-Source project]�hosted on Google Code, JMX Builder has been
+integrated in Groovy 1.6, to simplify the life of developers needing to
+interact or expose JMX services. JMX Builder features:
+
+* Domain Specific Language (DSL) for JMX API using Builder pattern
+* Simplified JMX API\u2019s programmability
+* Declaratively expose Java/Groovy objects as JMX managed MBeans
+* Support class-embedded or explicit descriptors
+* Inherent support for JMX\u2019s event model
+* Seamlessly create JMX event broadcasters
+* Attach event listeners as inline closures
+* Use Groovy\u2019s dynamic nature to easily react to JMX events
+notifications
+* Provides a flexible registration policy for MBean
+* No special interfaces or class path restrictions
+* Shields developer from complexity of JMX API
+* Exposes attribute, constructors, operations, parameters, and
+notifications
+* Simplifies the creation of connector servers and connector clients
+* Support for exporting JMX timers
+
+You can find�link:../jmx.html[more information on JMX Builder]�and its very extensive coverage of the JMX
+system. Lots of examples will show you how to create a JMX connector
+server or client, how to easily export POGOs as JMX managed beans, how
+to listen to JMX events, and much more.
+
+[[Groovy16releasenotes-ImprovedOSGisupport]]
+== Improved OSGi support
+
+The Groovy jar files are released with correct OSGi metadata, so they
+can be loaded as a bundle into any OSGi compliant container, such as
+Eclipse Equinox or Apache Felix.
+
+[[Groovy16releasenotes-Summary]]
+== Summary
+
+Groovy continues its march towards the goal of�*simplifying the life of
+developers*, providing various new features and improvements in this new
+release: AST transformations reducing dramatically the number of lines
+of code to express certain concerns and patterns and opening the
+language to developers for further extension, several�*metaprogramming
+enhancements to streamline your code*�and let you write�*more expressive
+business rules*, and�*support for common enterprise APIs*�such as Java
+6\u2019s scripting APIs, JMX management system, or OSGi\u2019s programming model.
+All of this is done obviously�*without compromising on the seamless
+integration with Java*, and furthermore, with a�*level of performance
+way higher than previous releases*.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy-user-site/blob/33e32ad0/site/src/site/releasenotes/groovy-1.7.adoc
----------------------------------------------------------------------
diff --git a/site/src/site/releasenotes/groovy-1.7.adoc b/site/src/site/releasenotes/groovy-1.7.adoc
new file mode 100644
index 0000000..cf401a0
--- /dev/null
+++ b/site/src/site/releasenotes/groovy-1.7.adoc
@@ -0,0 +1,433 @@
+[[Groovy17releasenotes-IDESupport]]
+== IDE Support
+
+Before diving directly into the new features in Groovy 1.7, please let
+me mention the great progress made in terms of IDE support for Groovy
+(and also for http://griffon-framework.org/[Griffon],
+http://gradle.org/[Gradle], https://gant.github.io/[Gant] or
+http://grails.org/[Grails]). All the major IDEs (Eclipse,
+http://www.jetbrains.com/idea/features/groovy_grails.html[IntelliJ
+IDEA], http://wiki.netbeans.org/Groovy[NetBeans]) provide an excellent
+level of support for the language. Initially, the Eclipse support was
+the one lacking the most, but thanks to the hard work of the
+SpringSource Eclipse team, we now have a great environment for
+developing mixed Java / Groovy applications with features like
+cross-language refactoring, Groovy-specific code completion, and more.
+
+New and Improved Eclipse pluginFor more information on the Eclipse
+support, please have a look at the Groovy Eclipse plugin home page, as
+well as the notes for the M1 release and M2 release.
+
+[[Groovy17releasenotes-Newfeatures]]
+== New features
+
+[[Groovy17releasenotes-AnonymousInnerClassesandNestedClasses]]
+=== Anonymous Inner Classes and Nested Classes
+
+Although oftentimes closures and maps coercion suffice, there are still
+areas where the lack of Anonymous Inner Classes (AIC) and Nested Classes
+(NC) can be problematic. That\u2019s why we decided to eventually implement
+AIC and NC in Groovy 1.7.
+
+Be CarefulThe implementation of AIC and NC follows the Java lead, but
+you should not take out the Java Language Spec and keep shaking the head
+about things that are different. The implementation done looks much like
+what we do for groovy.lang.Closure, with some benefits and some
+differences. Accessing private fields and methods for example can become
+a problem, but on the other hand local variables don\u2019t have to be final.
+
+[[Groovy17releasenotes-NestedStaticClasses]]
+==== Nested Static Classes
+
+Here\u2019s an example of Nested Static Classes:
+
+[source,groovy]
+---------------------
+class A {
+    static class B {}
+}
+
+new A.B()
+---------------------
+
+The usage of static nested classes is the best supported one. If you
+absolutely need an inner class, you should make it a static one.
+
+[[Groovy17releasenotes-AnonymousInnerClasses]]
+==== Anonymous Inner Classes
+
+Some other examples, this time for Anonymous Inner Classes:
+
+[source,groovy]
+--------------------------------
+boolean called = false
+
+Timer timer = new Timer()
+timer.schedule(new TimerTask() {
+    void run() {
+        called = true
+    }
+}, 0)
+sleep 100
+
+assert called
+--------------------------------
+
+More informationIf you want to learn a bit more about the cases which
+are currently supported in 1.7, you can have a look at one of our unit
+tests covering this new feature.
+
+[[Groovy17releasenotes-AccessingtheOuterContextfromaNestedClass]]
+==== Accessing the Outer Context from a Nested Class
+
+If you are in a nested class Y and the surrounding class is X, then you
+can access the variable v of X in Java by X.this.v. Groovy does not
+support this syntax.
+
+[[Groovy17releasenotes-CreatingInstancesofNon-StaticInnerClasses]]
+==== Creating Instances of Non-Static Inner Classes
+
+In Java you can do this:
+
+[source,java]
+----------------------------------
+public class Y {
+    public class X {}
+    public X foo() {
+        return new X();
+    }
+    public static X createX(Y y) {
+        return y.new X();
+    }
+}
+----------------------------------
+
+It should be noted that the nested class X needs a reference to the
+outer class instance of Y. For this Java will create a constructor that
+takes Y as first parameter in X. This constructor is synthetic, so it
+won\u2019t appear in any code completion. +
+ In case of new X(), like you have it in method foo(), then compiler
+will then create new X(this) instead. In case of createX the compiler
+will create new X(y). Groovy does not support this.
+
+Instead Groovy supports giving the instance in like the compiler would
+do it. That means the code above has to be rewritten as
+
+[source,groovy]
+----------------------------------
+public class Y {
+    public class X {}
+    public X foo() {
+        return new X(this);
+    }
+    public static X createX(Y y) {
+        return new X(y);
+    }
+}
+----------------------------------
+
+CautionCaution though, Groovy supports calling methods with one
+parameter without giving an argument. The parameter will then have the
+value null. Basically the same rules apply to calling a constructor.
+There is a danger that you will write new X() instead of new X(this) for
+example. Since this might also be the regular way we have not yet found
+a good way to prevent this problem.
+
+[[Groovy17releasenotes-Annotations]]
+=== Annotations
+
+Groovy\u2019s support of annotations is identical to Java 5 annotations, but
+we felt that in some cases it would be interesting to be able to add
+annotations in other places than the usual places (types, fields,
+methods, parameters, etc.). For instance, in Java, it is impossible to
+add annotations on imports or packages. Groovy does go beyond and adds
+support for annotation on imports, packages and variable declarations.
+We\u2019ll take a look at the usage of those extended annotations on Grape.
+
+[[Groovy17releasenotes-Grape]]
+==== Grape
+
+The Grape dependency system lets you request dependencies in your
+scripts, without having to deal with downloading, packaging, or
+specifying the classpath yourself. To use Grape, we had to use the @Grab
+annotation to ``grab'' a dependency from a repository (Maven\u2019s central
+repository, for example). The problem was that annotation had to be
+attached to some allowed elements, ie. the places where annotations can
+be put in Java. Now, we can put annotations on imports:
+
+[source,groovy]
+------------------------------------------------------------------------------------
+@Grab(group='net.sf.json-lib', module='json-lib', version='2.3', classifier='jdk15')
+import net.sf.json.groovy.*
+
+assert new JsonSlurper().parseText(
+    new JsonGroovyBuilder().json {
+        book(title: "Groovy in Action", author:"Dierk K�nig et al")
+    }.toString()
+).book.title == 'Groovy in Action'
+------------------------------------------------------------------------------------
+
+Another example with @Grab on variable declarations:
+
+[source,groovy]
+--------------------------------------------------------------------------------------------------------
+@Grab('net.sf.json-lib:json-lib:2.3:jdk15')
+def builder = new net.sf.json.groovy.JsonGroovyBuilder()
+
+def books = builder.books {
+    book(title: "Groovy in Action", author: "Dierk Koenig")
+}
+
+assert books.toString() == '''{"books":{"book":{"title":"Groovy in Action","author":"Dierk Koenig"}}}'''
+--------------------------------------------------------------------------------------------------------
+
+RemarkPlease note on this one an improvement in the @Grab annotation: we
+provide a shorter version taking just a String as value parameter
+representing the dependency, in addition to the more verbose example in
+the previous example. You simply append the group, module, version and
+classifier together, joined by colons.
+
+A Grape *resolver* was added, so you can specify a remote location where
+grapes are downloaded from:
+
+[source,groovy]
+------------------------------------------------------------------
+@GrabResolver(name='restlet.org', root='http://maven.restlet.org')
+@Grab(group='org.restlet', module='org.restlet', version='1.1.6')
+import org.restlet.Restlet
+// ...
+------------------------------------------------------------------
+
+[[Groovy17releasenotes-PowerAsserts]]
+=== Power Asserts
+
+Groovy\u2019s ``assert'' keyword has sometimes been criticized as it\u2019s, in a
+way, limited, as it just checks that the expression it\u2019s being passed is
+true or false. Unlike with testing frameworks such as JUnit/TestNG and
+the various additional assertion utilities, where you get nicer and more
+descriptive messages, Groovy\u2019s assert would just tell you the expression
+was false, and would give the value of variables used in the expression,
+but nothing more. With Power Asserts, initially developed in the
+http://spockframework.org/[Spock Framework], the output of the assert is
+now much nicer and provides a visual representation of the value of each
+sub-expressions of the expression being asserted. For example:
+
+[source,groovy]
+-----------------------------------------------------
+assert new File('foo.bar') == new File('example.txt')
+-----------------------------------------------------
+
+Will yield:
+
+[source,groovy]
+-----------------------------------------------------
+Caught: Assertion failed:
+
+assert new File('foo.bar') == new File('example.txt')
+       |                   |  |
+       foo.bar             |  example.txt
+                           false
+-----------------------------------------------------
+
+[[Groovy17releasenotes-AST]]
+=== AST
+
+With Groovy 1.6, we introduced AST Transformations, for letting
+developers do compile-time metaprogramming, by modifying the Abstract
+Syntax Tree before it is transformed into bytecode. In Groovy 1.6,
+several such transformations were added, especially ``local''
+transformations triggered by annotations (such as @Delegate, @Singleton,
+@Bindable and friends). However powerful this feature is, writing AST
+transformation has always been a bit tedious. Groovy 1.7 features two
+new features which should help simplify the work of AST transformation
+writers: an AST viewer and an AST builder.
+
+[[Groovy17releasenotes-ASTViewer]]
+==== AST Viewer
+
+The following screenshot shows a new window that can be launched from
+the Groovy Swing Console. You can visualize the AST of a script you\u2019re
+working on in the console: for instance, writing the code you\u2019d like to
+create in your AST transformation. The AST viewer greatly help with
+figuring out how Groovy builds its AST when compiling your Groovy
+code. +
+ image:attachments/126320769/134184968.png[image]
+
+[[Groovy17releasenotes-ASTBuilder]]
+==== AST Builder
+
+Visualizing the AST is one thing, but we also need a mechanism to create
+and modify ASTs more easily. The introduction of the AST builder
+simplifies the authoring of AST transformations, by giving you three
+different approaches for working on the AST:
+
+* building from string
+* building from code
+* building from specification
+
+Before the AST builder, one had to create and instantiate manually all
+the various AST nodes. Let\u2019s see how those three forms help with this,
+for instance for creating a node representing a constant string.
+
+[[Groovy17releasenotes-Buildingfromstring]]
+===== Building from string
+
+[source,groovy]
+-----------------------------------------------------------------------
+List<ASTNode> nodes = new AstBuilder().buildFromString(''' "Hello" ''')
+-----------------------------------------------------------------------
+
+[[Groovy17releasenotes-Buildingfromcode]]
+===== Building from code
+
+[source,groovy]
+----------------------------------------------------------------
+List<ASTNode> nodes = new AstBuilder().buildFromCode { "Hello" }
+----------------------------------------------------------------
+
+[[Groovy17releasenotes-Buildingfromspecification]]
+====== Building from specification
+
+[source,groovy]
+------------------------------------------------------
+List<ASTNode> nodes = new AstBuilder().buildFromSpec {
+    block {
+        returnStatement {
+            constant "Hello"
+        }
+    }
+}
+------------------------------------------------------
+
+For more informationPlease have a look at the documentation on the AST
+Builder. You\u2019ll discover the advantages and inconveniences of the
+various forms, and why all three are needed depending on what you want
+to achieve with the AST.
+
+[[Groovy17releasenotes-Otherminorenhancements]]
+Other minor enhancements
+------------------------
+
+[[Groovy17releasenotes-AbilitytocustomizetheGroovyTruth]]
+=== Ability to customize the Groovy Truth
+
+In Groovy, booleans aren\u2019t the sole things which can be evaluated to
+true or false, but for instance, null, empty strings or collections are
+evaluated to false or true if of length > 0 or non-empty. This notion of
+'truth' was coined 'Groovy Truth' in the
+http://www.manning.com/koenig/[Groovy in Action] book. With Groovy
+Truth, instead of doing frequent null checks, you could simply write:
+
+[source,groovy]
+--------------------------------------------------------------
+def string = "more than one character"
+if (string) { println "the String is neither null nor empty" }
+--------------------------------------------------------------
+
+Up until Groovy 1.7, only a small set of classes had a certain meaning
+with regards to how they were coerced to a boolean value, but now it is
+possible to provide a method for coercion to boolean in your own
+classes. For example, the following Predicate class offers the ability
+to coerce Predicate instances to true or false, thanks to the
+implementation of the boolean asBoolean() method:
+
+[source,groovy]
+-----------------------------------
+class Predicate {
+    boolean value
+    boolean asBoolean() { value }
+}
+
+assert new Predicate(value: true)
+assert !new Predicate(value: false)
+-----------------------------------
+
+Is is also possible to use categories or ExpandoMetaClass to inject an
+asBoolean() method, or to override an existing one (even one on the
+small set of classes with special Groovy truth behavior).
+
+[[Groovy17releasenotes-Dependencyupgrades]]
+=== Dependency upgrades
+
+Some of the dependencies of Groovy have been upgraded to newer versions.
+
+For instance, Groovy now uses the latest ASM version, which is
+``invokedynamic''-ready. So as we progress towards the inclusion of
+JSR-292 / invokedynamic, we\u2019ll be ready and be using the latest version
+of ASM. We also use the latest version of Ivy which is used by the Grape
+dependency module.
+
+[[Groovy17releasenotes-RewriteoftheGroovyScriptEngine]]
+=== Rewrite of the GroovyScriptEngine
+
+The GroovyScriptEngine (which is also used by Groovlets) has been
+rewritten to solve various dependency issues it was suffering from, and
+the outcome of this is that it should also now be much faster overall.
+
+The new logic uses additional phase operations to track dependencies. As
+a result the error-prone class loader technique to track them is gone
+now. These operations ensure that every script file will be tracked, its
+dependencies recorded during compilation and all transitive dependencies
+will be calculated. And only scripts will be recorded as dependency, no
+classes. The new GroovyScriptEngine also uses only one compilation
+``process'' for script compilation which solves the problem of circular
+or mutual dependencies, that caused stack overflows in the past. As a
+result the new engine can reliably handle dependencies and should be
+much faster.�
+
+[[Groovy17releasenotes-Groovyconsolepreferences]]
+=== Groovy console preferences
+
+A small annoyance, especially for developers using big LCD screens: the
+Groovy Console didn\u2019t remember preferences of position of the separator
+between the coding area and output view, or the font size being used.
+This is now fixed, as the console remembers such settings. You won\u2019t
+need anymore to adjust the console to your liking each time you run it,
+it should now have some more brain cells to remember your preferences.
+
+[[Groovy17releasenotes-NewoutputwindowfortheGroovyconsole]]
+=== New output window for the Groovy console
+
+There is a new visualization option for the results of the execution of
+your scripts in your Groovy Console. Instead of displaying the results
+in the bottom output pane, it\u2019s now possible to use an external window
+for viewing those results. Run your script with CTRL-R or CMD-R, you
+will see something like the following screenshot. You can then dismiss
+the window by hitting Escape, CTRL-W (CMD-W on Macs) or Enter.
+image:attachments/126320769/135528463.png[image] +
+ You will also notice the addition of line numbers in the gutter of the
+editor area.
+
+[[Groovy17releasenotes-SQLbatchupdatesandtransactions]]
+=== SQL batch updates and transactions
+
+[[Groovy17releasenotes-Batchupdates]]
+==== Batch updates
+
+The Groovy Sql class now features batch updates, thanks to its new
+withBatch() method, taking a closure and a statement instance:
+
+[source,groovy]
+----------------------------------------------------------------
+sql.withBatch { stmt ->
+    ["Paul", "Jochen", "Guillaume"].each { name ->
+        stmt.addBatch "insert into PERSON (name) values ($name)"
+    }
+}
+----------------------------------------------------------------
+
+[[Groovy17releasenotes-Transactions]]
+==== Transactions
+
+Similarly, there\u2019s a withTransaction() method added to Sql, which works
+also with datasets:
+
+[source,groovy]
+-----------------------------------
+def persons = sql.dataSet("person")
+sql.withTransaction {
+    persons.add name: "Paul"
+    persons.add name: "Jochen"
+    persons.add name: "Guillaume"
+}
+-----------------------------------