//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Groovy style and language feature guidelines for Java developers

A Java developer embarking on a Groovy adventure will always have Java in mind, and will progressively learn Groovy,
one feature at a time, becoming more productive and writing more idiomatic Groovy code.
This document's purpose is to guide such a developer along the way, teaching some common Groovy syntax style,
new operators, and new features like closures, etc.
This guide is not complete and only serves as a quick intro and a base for further guideline sections
should you feel like contributing to the document and enhancing it.

== No semicolons

When coming from a C / C++ / C# / Java background, we're so used to semicolons, that we put them everywhere.
Even worse, Groovy supports 99% of Java's syntax, and sometimes,
it's so easy to paste some Java code into your Groovy programs, that you end up with tons of semicolons everywhere.
But... semicolons are optional in Groovy, you can omit them, and it's more idiomatic to remove them.

== Return keyword optional

In Groovy, the last expression evaluated in the body of a method can be returned without necessitating the `return` keyword.
Especially for short methods and for closures, it's nicer to omit it for brevity:

[source,groovy]
----
String toString() { return "a server" }
String toString() { "a server" }
----

But sometimes, this doesn't look too good when you're using a variable, and see it visually twice on two rows:

[source,groovy]
----
def props() {
    def m1 = [a: 1, b: 2]
    m2 = m1.findAll { k, v -> v % 2 == 0 }
    m2.c = 3
    m2
}
----

In such case, either putting a newline before the last expression, or explicitly using `return` may yield better readability.

I, for myself, sometimes use the `return` keyword, sometimes not, it's often a matter of taste.
But often, inside of closure, we omit it more often than not, for example. So even if the keyword is optional,
this is by no means mandatory to not use it if you think it halters the readability of your code.

A word of caution, however. When using methods which are defined with the `def` keyword instead of a specific concrete type,
you may be surprised to see the last expression being returned sometimes. So usually prefer using a specific return type like void or a type.
In our example above, imagine we forgot to put m2 as last statement to be returned,
the last expression would be `m2.c = 3`, which would return... `3`, and not the map you expect.

Statements like `if`/`else`, `try`/`catch` can thus return a value as well, as there's a "last expression" evaluated in those statements:

[source,groovy]
----
def foo(n) {
    if(n == 1) {
        "Roshan"
    } else {
        "Dawrani"
    }
}

assert foo(1) == "Roshan"
assert foo(2) == "Dawrani"
----

== Def and type

As we're talking about `def` and types, I often see developers using both `def` and a type. But `def` is redundant here.
So make a choice, either use `def` or a type.

So don't write:

[source,groovy]
----
def String name = "Guillaume"
----

But:

[source,groovy]
----
String name = "Guillaume"
----

When using `def` in Groovy, the actual type holder is `Object` (so you can assign any object to variables defined with `def`,
and return any kind of object if a method is declared returning `def`).

When defining a method with untyped parameters, you can use `def` but it's not needed, so we tend to omit them.
So instead of:

[source,groovy]
----
void doSomething(def param1, def param2) { }
----

Prefer:

[source,groovy]
----
void doSomething(param1, param2) { }
----

But as we mention in the last section of the document, it's usually better to type your method parameters,
so as to help with documenting your code, and also help IDEs for code-completion,
or for leveraging the static type checking or static compilation capabilities of Groovy.

Another place where `def` is redundant and should be avoided is when defining constructors:

[source,groovy]
----
class MyClass {
    def MyClass() {}
}
----

Instead, just remove the `def`:

[source,groovy]
----
class MyClass {
    MyClass() {}
}
----

== Public by default

By default, Groovy considers classes and methods `public`.
So you don't have to use the `public` modifier everywhere something is public.
Only if it's not public, you should put a visibility modifier.

So instead of:

[source,groovy]
----
public class Server {
    public String toString() { return "a server" }
}
----

Prefer the more concise:

[source,groovy]
----
class Server {
    String toString() { "a server" }
}
----

You may wonder about the 'package-scope' visibility,
and the fact Groovy allows one to omit 'public' means that this scope is not supported by default,
but there's actually a special Groovy annotation which allows you to use that visibility:

[source,groovy]
----
class Server {
    @PackageScope Cluster cluster
}
----

== Omitting parentheses

Groovy allows you to omit the parentheses for top-level expressions, like with the `println` command:

[source,groovy]
----
println "Hello"
method a, b
----

vs:

[source,groovy]
----
println("Hello")
method(a, b)
----

When a closure is the last parameter of a method call, like when using Groovy's `each{}` iteration mechanism,
you can put the closure outside the closing parentheses, and even omit the parentheses:

[source,groovy]
----
list.each( { println it } )
list.each(){ println it }
list.each  { println it }
----

Always prefer the third form, which is more natural, as an empty pair of parentheses is just useless syntactical noise!

In some cases parentheses are required, such as when making nested method calls or when calling a method without parameters.

[source,groovy]
----
def foo(n) { n }
def bar() { 1 }

println foo 1 // won't work
def m = bar   // won't work
----

== Classes as first-class citizens

The `.class` suffix is not needed in Groovy, a bit like in Java's `instanceof`.

For example:

[source,groovy]
----
connection.doPost(BASE_URI + "/modify.hqu", params, ResourcesResponse.class)
----

Using GStrings we're going to cover below, and using first class citizens:

[source,groovy]
----
connection.doPost("${BASE_URI}/modify.hqu", params, ResourcesResponse)
----

== Getters and Setters

In Groovy, a getters and setters form what we call a "property",
and offers a shortcut notation for accessing and setting such properties.
So instead of the Java-way of calling getters / setters, you can use a field-like access notation:

[source,groovy]
----
resourceGroup.getResourcePrototype().getName() == SERVER_TYPE_NAME
resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME

resourcePrototype.setName("something")
resourcePrototype.name = "something"
----

When writing your beans in Groovy, often called POGOs (Plain Old Groovy Objects),
you don't have to create the field and getter / setter yourself, but let the Groovy compiler do it for you.

So instead of:

[source,groovy]
----
class Person {
    private String name
    String getName() { return name }
    void setName(String name) { this.name = name }
}
----

You can simply write:

[source,groovy]
----
class Person {
    String name
}
----

As you can see, a free standing 'field' without modifier visibility actually
makes the Groovy compiler to generate a private field and a getter and setter for you.

When using such POGOs from Java, the getter and setter are indeed there, and can be used as usual, of course.

Although the compiler creates the usual getter/setter logic,
if you wish to do anything additional or different in those getters/setters,
you're free to still provide them, and the compiler will use your logic, instead of the default generated one.

== Initializing beans with named parameters and the default constructor

With a bean like:

[source,groovy]
----
class Server {
    String name
    Cluster cluster
}
----

Instead of setting each setter in subsequent statements as follows:

[source,groovy]
----
def server = new Server()
server.name = "Obelix"
server.cluster = aCluster
----

You can use named parameters with the default constructor (first the constructor is called, then the setters are called in the sequence in which they are specified in the map):

[source,groovy]
----
def server = new Server(name: "Obelix", cluster: aCluster)
----

== Using `with()` and `tap()` for repeated operations on the same bean

Named-parameters with the default constructor is interesting when creating new instances,
but what if you are updating an instance that was given to you, do you have to repeat the 'server' prefix again and again?
No, thanks to the `with()` and `tap()` methods that Groovy adds on all objects of any kind:

[source,groovy]
----
server.name = application.name
server.status = status
server.sessionCount = 3
server.start()
server.stop()
----

vs:

[source,groovy]
----
server.with {
    name = application.name
    status = status
    sessionCount = 3
    start()
    stop()
}
----

As with any closure in Groovy, the last statement is considered the return value.  In the example above this is the result of `stop()`.  To use this as a builder, that just returns the incoming object, there is also `tap()`:

[source,groovy]
----
def person = new Person().with {
    name = "Ada Lovelace"
    it // Note the explicit mention of it as the return value
}
----

vs:

[source,groovy]
----
def person = new Person().tap {
    name = "Ada Lovelace"
}
----

Note: you can also use `with(true)` instead of `tap()` and `with(false)` instead of `with()`.

== Equals and `==`

Java's `==` is actually Groovy's `is()` method, and Groovy's `==` is a clever `equals()`!

To compare the references of objects, instead of `==`, you should use `a.is(b)`.

But to do the usual `equals()` comparison, you should prefer Groovy's `==`,
as it also takes care of avoiding `NullPointerException`, independently of whether the left or right is `null` or not.

Instead of:

[source,groovy]
----
status != null && status.equals(ControlConstants.STATUS_COMPLETED)
----

Do:

[source,groovy]
----
status == ControlConstants.STATUS_COMPLETED
----

== GStrings (interpolation, multiline)

We often use string and variable concatenation in Java, with many opening `/` closing of double quotes, plus signs,
and `\n` characters for newlines.
 With interpolated strings (called GStrings), such strings look better and are less painful to type:

[source,groovy]
----
throw new Exception("Unable to convert resource: " + resource)
----

vs:

[source,groovy]
----
throw new Exception("Unable to convert resource: ${resource}")
----

Inside the curly braces, you can put any kind of expression, not just variables.
For simple variables, or `variable.property`, you can even drop the curly braces:

[source,groovy]
----
throw new Exception("Unable to convert resource: $resource")
----

You can even lazily evaluate those expressions using a closure notation with `${\-> resource }`.
When the GString will be coerced to a String, it'll evaluate the closure and get the `toString()` representation of the return value.

Example:

[source,groovy]
----
int i = 3

def s1 = "i's value is: ${i}"
def s2 = "i's value is: ${-> i}"

i++

assert s1 == "i's value is: 3" // eagerly evaluated, takes the value on creation
assert s2 == "i's value is: 4" // lazily evaluated, takes the new value into account
----

When strings and their concatenated expression are long in Java:

[source,groovy]
----
throw new PluginException("Failed to execute command list-applications:" +
    " The group with name " +
    parameterMap.groupname[0] +
    " is not compatible group of type " +
    SERVER_TYPE_NAME)
----

You can use the `\` continuation character (this is not a multiline string):

[source,groovy]
----
throw new PluginException("Failed to execute command list-applications: \
The group with name ${parameterMap.groupname[0]} \
is not compatible group of type ${SERVER_TYPE_NAME}")
----

Or using multiline strings with triple quotes:

[source,groovy]
----
throw new PluginException("""Failed to execute command list-applications:
    The group with name ${parameterMap.groupname[0]}
    is not compatible group of type ${SERVER_TYPE_NAME)}""")
----

You can also strip the indentation appearing on the left side of the multiline strings by calling `.stripIndent()` on that string.

Also note the difference between single quotes and double quotes in Groovy: single quotes always create Java Strings,
without interpolation of variables, whereas double quotes either create Java Strings or GStrings when interpolated variables are present.

For multiline strings, you can triple the quotes: i.e. triple double quotes for GStrings and triple single quotes for mere Strings.

If you need to write regular expression patterns, you should use the "slashy" string notation:

[source,groovy]
----
assert "foooo/baaaaar" ==~ /fo+\/ba+r/
----

The advantage of the "slashy" notation is that you don't need to double escape backslashes, making working with regex a bit simpler.

Last but not least, prefer using single quoted strings when you need string constants,
and use double quoted strings when you are explicitly relying on string interpolation.

== Native syntax for data structures

Groovy provides native syntax constructs for data structures like lists, maps, regex, or ranges of values.
Make sure to leverage them in your Groovy programs.

Here are some examples of those native constructs:

[source,groovy]
----
include::{projectdir}/src/spec/test/StyleGuideTest.groovy[tags=data_structures,indent=0]
----

== The Groovy Development Kit

Continuing on the data structures, when you need to iterate over collections,
Groovy provides various additional methods, decorating Java's core data structures,
like `each{}`, `find{}`, `findAll{}`, `every{}`, `collect{}`, `inject{}`.
These methods add a functional flavor to the programming language and help working with complex algorithms more easily.
Lots of new methods are applied to various types, through decoration, thanks to the dynamic nature of the language.
You can find lots of very useful methods on String, Files, Streams, Collections, and much more:

http://groovy-lang.org/gdk.html

== The power of switch

Groovy's `switch` is much more powerful than in C-ish languages which usually only accept primitives and assimilated.
Groovy's `switch` accepts pretty much any kind of type.

[source,groovy]
----
def x = 1.23
def result = ""
switch (x) {
    case "foo": result = "found foo"
    // lets fall through
    case "bar": result += "bar"
    case [4, 5, 6, 'inList']:
        result = "list"
        break
    case 12..30:
        result = "range"
        break
    case Integer:
        result = "integer"
        break
    case Number:
        result = "number"
        break
    case { it > 3 }:
        result = "number > 3"
        break
    default: result = "default"
}
assert result == "number"
----

And more generally, types with an `isCase()` method can also decide whether a value corresponds with a case

== Import aliasing

In Java, when using two classes of the same name but from different packages, like `java.util.List`
and `java.awt.List`, you can import one class, but have to use a fully-qualified name for the other.

Also sometimes, in your code, multiple usages of a long class name, can increase verbosity and
reduce clarity of the code.

To improve such situations, Groovy features import aliasing:

[source,groovy]
----
import java.util.List as UtilList
import java.awt.List as AwtList
import javax.swing.WindowConstants as WC

UtilList list1 = [WC.EXIT_ON_CLOSE]
assert list1.size() instanceof Integer
def list2 = new AwtList()
assert list2.size() instanceof java.awt.Dimension
----

You can also use aliasing when importing methods statically:

[source,groovy]
----
import static java.lang.Math.abs as mabs
assert mabs(-4) == 4
----

== Groovy Truth

All objects can be 'coerced' to a boolean value: everything that's `null`, `void`, equal to zero,
or empty evaluates to `false`, and if not, evaluates to `true`.

So instead of writing:

[source,groovy]
----
if (name != null && name.length > 0) {}
----

You can just do:

[source,groovy]
----
if (name) {}
----

Same thing for collections, etc.

Thus, you can use some shortcuts in things like `while()`, `if()`, the ternary operator, the Elvis operator (see below), etc.

It's even possible to customize the Groovy Truth, by adding an boolean `asBoolean()` method to your classes!

== Safe graph navigation

Groovy supports a variant of the `.` operator to safely navigate an object graph.

In Java, when you're interested in a node deep in the graph and need to check for `null`,
you often end up writing complex `if`, or nested `if` statements like this:

[source,groovy]
----
if (order != null) {
    if (order.getCustomer() != null) {
        if (order.getCustomer().getAddress() != null) {
            System.out.println(order.getCustomer().getAddress());
        }
    }
}
----

With `?.` safe dereference operator, you can simplify such code with:

[source,groovy]
----
println order?.customer?.address
----

Nulls are checked throughout the call chain and no `NullPointerException` will be thrown if any element is `null`,
and the resulting value will be null if something's `null`.

== Assert

To check your parameters, your return values, and more, you can use the `assert` statement.

Contrary to Java's `assert`, `assert`s don't need to be activated to be working, so `assert`s are always checked.

[source,groovy]
----
def check(String name) {
    // name non-null and non-empty according to Groovy Truth
    assert name
    // safe navigation + Groovy Truth to check
    assert name?.size() > 3
}
----

You'll also notice the nice output that Groovy's "Power Assert" statement provides,
with a graph view of the various values of each sub-expressions being asserted.

== Elvis operator for default values

The Elvis operator is a special ternary operator shortcut which is handy to use for default values.

We often have to write code like:

[source,groovy]
----
def result = name != null ? name : "Unknown"
----

Thanks to Groovy Truth, the `null` check can be simplified to just 'name'.

And to go even further, since you return 'name' anyway, instead of repeating name twice in this ternary expression,
we can somehow remove what's in between the question mark and colon, by using the Elvis operator, so that the above becomes:

[source,groovy]
----
def result = name ?: "Unknown"
----

== Catch any exception

If you don't really care about the type of the exception which is thrown inside your `try` block,
you can simply catch any of them and simply omit the type of the caught exception.
So instead of catching the exceptions like in:

[source,groovy]
----
try {
    // ...
} catch (Exception t) {
    // something bad happens
}
----

Then catch anything ('any' or 'all', or whatever makes you think it's anything):

[source,groovy]
----
try {
    // ...
} catch (any) {
    // something bad happens
}
----

[NOTE]
Note that it's catching all Exceptions, not `Throwable`s. If you need to really catch "everything",
you'll have to be explicit and say you want to catch `Throwable`s.

== Optional typing advice

I'll finish on some words on when and how to use optional typing.
Groovy lets you decide whether you use explicit strong typing, or when you use `def`.

I've got a rather simple rule of thumb: whenever the code you're writing is going to be used by others as a public API,
you should always favor the use of strong typing, it helps making the contract stronger,
avoids possible passed arguments type mistakes, gives better documentation, and also helps the IDE with code completion.
Whenever the code is for your use only, like private methods,
or when the IDE can easily infer the type, then you're more free to decide when to type or not.
