Run Grails Commands on Heroku
May 22nd, 2014
Instructions on how to run Grails commands on Heroku using an example of how to run Grails migrations on Heroku
Inline initialization of maps in Java has been a sign of weakness in the Java language. This approach has given me the most concise way to initialize maps, while meeting all of my goals.
Goals:
I have found articles and 3rd part libraries that come close, and my be the idea choice for you. However, none met all of the goals above, so I kept looking for a new solution (I know, goals like ‘minimal syntax’ is up for debate, if I actually achieved that).
If you include MapUtils, which is less than 50 lines of code, and you statically import one of the methods, MapUtils.entry() you can initialize a Map as follows:
Map<String,Integer> map = MapUtils.asMap(entry(“A”, 1), entry(“B”, 2), entry(“C”, 3), entry(“D”, 4)); Map<String,Integer> map = MapUtils.asUnmodifiableMap(entry(“A”, 1), entry(“B”, 2), entry(“C”, 3), entry(“D”, 4));
Here is the source code for MapUtils.java
package com.objectpartners.buesing.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author Neil Buesing
*/
public final class MapUtils {
public static class Entry<K, V> {
private K key;
private V value;
public Entry(final K key, final V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
public static <K, V> Entry<K, V> entry(final K key, final V value) {
return new Entry(key, value);
}
public static <K, V> Map<K, V> asMap(final Entry<K, V>... entries) {
return populate(new HashMap<K, V>(), entries);
}
public static <K, V> Map<K, V> asOrderedMap(final Entry<K, V>... entries) {
return populate(new LinkedHashMap<K, V>(), entries);
}
public static <K, V> Map<K, V> asUnmodifiableMap(final Entry<K, V>... entries) {
return Collections.unmodifiableMap(populate(new HashMap<K, V>(), entries));
}
public static <K, V> Map<K, V> asUnmodifiableOrderedMap(final Entry<K, V>... entries) {
return Collections.unmodifiableMap(populate(new LinkedHashMap<K, V>(), entries));
}
private static <K, V> Map<K, V> populate(final Map map, final Entry<K, V>... entries) {
for (final Entry entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
}
This is a simple unit test showing various ways to initialize inline maps; compare and see what technique you like best.
package com.objectpartners.buesing.util;
import com.google.common.collect.ImmutableMap;
import org.junit.Assert;
import org.junit.Test;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static com.objectpartners.buesing.util.MapUtils.entry;
/**
* @author Neil Buesing
*/
public class MapInitializationTest {
//the approach described in this blog
private Map<String, Integer> mapA = MapUtils.asMap(entry("A", 1), entry("B", 2));
//the approach described in this blog (unmodifiable)
private Map<String, Integer> mapB = MapUtils.asUnmodifiableMap(entry("A", 1), entry("B", 2));
//block initialization
private Map<String, Integer> mapC = new HashMap<String, Integer>();
{
mapA.put("A", 1);
mapA.put("B", 2);
}
//block initialization / unmodifiable
private Map<String, Integer> mapD;
{
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 1);
map.put("B", 2);
mapD = Collections.unmodifiableMap(map);
}
//inheritance with block initialization
private Map<String, Integer> mapE = new HashMap<String, Integer>() {{
put("A", 1);
put("B", 2);
}};
//3rd party library Guava
private Map mapF = ImmutableMap.builder().put("A", 1).put("B", 2).build();
@Test
public void test() {
Assert.assertEquals(mapA, mapB);
Assert.assertEquals(mapA, mapC);
Assert.assertEquals(mapA, mapD);
Assert.assertEquals(mapA, mapE);
Assert.assertEquals(mapA, mapF);
}
}
For completeness sake, here is a unit test MapUtilsTest.java
package com.objectpartners.buesing.util;
import org.junit.Assert;
import org.junit.Test;
import javax.naming.OperationNotSupportedException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import static com.objectpartners.buesing.util.MapUtils.entry;
/**
* @author Neil Buesing
*/
public class MapUtilsTest {
@Test
public void testAsMap() {
Map<String, Integer> map = MapUtils.asMap(entry("A", 1), entry("B", 2));
Assert.assertEquals(2, map.size());
Assert.assertEquals(Integer.valueOf(1), map.get("A"));
Assert.assertEquals(Integer.valueOf(2), map.get("B"));
}
@Test
public void testAsOrderedMap() {
Map<String, Integer> map = MapUtils.asOrderedMap(
entry("Z", 1), entry("Y", 9), entry("X", 2), entry("W", 7), entry("C", 3), entry("B", 6), entry("A", 4)
);
Assert.assertEquals(7, map.size());
Assert.assertEquals(Arrays.asList("Z", "Y", "X", "W", "C", "B", "A"), new ArrayList<String>(map.keySet()));
Assert.assertEquals(Arrays.asList(1, 9, 2, 7, 3, 6, 4), new ArrayList<Integer>(map.values()));
}
@Test
public void testAsUnmodifiableMap() {
Map<String, Integer> map = MapUtils.asUnmodifiableMap(entry("A", 1), entry("B", 2));
Assert.assertEquals(2, map.size());
Assert.assertEquals(Integer.valueOf(1), map.get("A"));
Assert.assertEquals(Integer.valueOf(2), map.get("B"));
try {
map.put("AA", 33);
Assert.fail("failed to throw exception");
} catch (UnsupportedOperationException e) {
// expected
}
}
@Test
public void testAsUnmodifiableOrderedMap() {
Map<String, Integer> map = MapUtils.asUnmodifiableOrderedMap(
entry("Z", 1), entry("Y", 9), entry("X", 2), entry("W", 7), entry("C", 3), entry("B", 6), entry("A", 4)
);
Assert.assertEquals(7, map.size());
Assert.assertEquals(Arrays.asList("Z", "Y", "X", "W", "C", "B", "A"), new ArrayList<String>(map.keySet()));
Assert.assertEquals(Arrays.asList(1, 9, 2, 7, 3, 6, 4), new ArrayList<Integer>(map.values()));
try {
map.put("AA", 33);
Assert.fail("failed to throw exception");
} catch (UnsupportedOperationException e) {
// expected
}
}
}
Now, maybe someday, Java will learn from Groovy and add these higher level data structure concepts to the language. While I can appreciate a language that tries not to embedded higher-level object concepts into the core, Java has already crossed this line with the introduction of Java5 for-loop syntax. Also, from Java’s beginning, making String objects from character arrays. In the meantime we all search the web and find various techniques to try to reduce the amount of Java code we write. Maybe someday I can work on an application server that allows me to utilize Java 8 and I can finally have my lambda expressions; or at least Java’s implementation and I can start getting rid of more of the boiler plate code I’m forced to write. For now, I will just be happy with my inlined initialized Maps.
Instructions on how to run Grails commands on Heroku using an example of how to run Grails migrations on Heroku
It can take a little digging to move Spring Security + CAS XML configuration to Java. Here is the Java config equivalent to the SS documentations example.
A script to grab the list of modified files from git, parse their filenames, and pass those names for testing in grails test-app.