Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AliasMap is no more a map, but instead comuptes an immutable map
- Loading branch information
pith
committed
Mar 7, 2016
1 parent
f7cfbdd
commit fbe924c
Showing
5 changed files
with
302 additions
and
53 deletions.
There are no files selected for viewing
91 changes: 52 additions & 39 deletions
91
core/src/main/java/io/nuun/kernel/core/internal/AliasMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,73 +1,86 @@ | ||
package io.nuun.kernel.core.internal; | ||
|
||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import io.nuun.kernel.core.KernelException; | ||
|
||
import java.util.*; | ||
|
||
/** | ||
* | ||
* | ||
* @author epo.jemba{@literal @}kametic.com | ||
*/ | ||
public class AliasMap extends HashMap<String, String> | ||
public class AliasMap | ||
{ | ||
private static final long serialVersionUID = 1L; | ||
Map<String, String> aliases = new HashMap<String, String>(); | ||
private Map<String, String> aliases = new HashMap<String, String>(); | ||
private Map<String, String> params = new HashMap<String, String>(); | ||
|
||
/** | ||
* @param key | ||
* the key to alias. | ||
* @param alias | ||
* the alias to give to the key. | ||
* @return | ||
* @param key the key to alias. | ||
* @param alias the alias to give to the key. | ||
* @return the previous alias corresponding the key | ||
*/ | ||
public String putAlias(String key, String alias) | ||
public String putAlias(String alias, String key) | ||
{ | ||
if (super.containsKey(alias)) | ||
if (aliases.containsKey(key)) | ||
{ | ||
throw new IllegalArgumentException("alias " + alias + " already exists in map."); | ||
throw new IllegalArgumentException("The key \"" + key + "\" to alias is already present in the kernel parameters."); | ||
} | ||
return aliases.put(alias, key); | ||
return aliases.put(key, alias); | ||
} | ||
|
||
public String get(String key) | ||
{ | ||
List<String> cache = new ArrayList<String>(); | ||
return getWithAlias(key, cache); | ||
} | ||
|
||
@Override | ||
public String get(Object key) | ||
private String getWithAlias(String key, List<String> cache) | ||
{ | ||
String keyAlias = aliases.get(key); | ||
if (keyAlias == null) | ||
if (cache.contains(key)) | ||
{ | ||
return super.get(key); | ||
throw new KernelException("Cycle detected in kernel parameter aliases."); | ||
} | ||
else | ||
cache.add(key); | ||
String alias = aliases.get(key); | ||
if (alias == null) | ||
{ | ||
return super.get(keyAlias); | ||
return params.get(key); | ||
} else | ||
{ | ||
return getWithAlias(alias, cache); | ||
} | ||
} | ||
|
||
public boolean containsAllKeys(Collection<String> computedMandatoryParams) | ||
public String put(String key, String value) | ||
{ | ||
HashSet<String> allKeys = new HashSet<String>(); | ||
allKeys.addAll(keySet()); | ||
allKeys.addAll(aliases.values()); | ||
return params.put(key, value); | ||
} | ||
|
||
Collection<String> trans = new HashSet<String>(); | ||
for (String s : computedMandatoryParams) | ||
public Map<String, String> toMap() | ||
{ | ||
Map<String, String> map = new HashMap<String, String>(params); | ||
for (Map.Entry<String, String> entry : aliases.entrySet()) | ||
{ | ||
String string = aliases.get(s); | ||
if (string != null) | ||
String alias = entry.getKey(); | ||
String paramKey = entry.getValue(); | ||
map.put(alias, get(paramKey)); | ||
} | ||
return Collections.unmodifiableMap(map); | ||
} | ||
|
||
public boolean containsAllKeys(Collection<String> keys) | ||
{ | ||
for (String key : keys) | ||
{ | ||
if (!containsKey(key)) | ||
{ | ||
trans.add(string); | ||
return false; | ||
} | ||
} | ||
|
||
return allKeys.containsAll(trans); | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean containsKey(Object key) | ||
public boolean containsKey(String key) | ||
{ | ||
return aliases.containsKey(key) ? true : super.containsKey(key); | ||
return aliases.containsKey(key) || params.containsKey(key); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
core/src/test/java/io/nuun/kernel/core/internal/AliasMapTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package io.nuun.kernel.core.internal; | ||
|
||
import com.google.common.collect.Lists; | ||
import io.nuun.kernel.core.KernelException; | ||
import org.assertj.core.api.Assertions; | ||
import org.junit.Test; | ||
|
||
import static org.assertj.core.data.MapEntry.entry; | ||
|
||
/** | ||
* @author Pierre THIROUIN (pierre.thirouin@ext.inetpsa.com) | ||
*/ | ||
public class AliasMapTest | ||
{ | ||
@Test | ||
public void testAccessNormalParam() throws Exception | ||
{ | ||
AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("param", "val1"); | ||
|
||
Assertions.assertThat(aliasMap.get("param")).isEqualTo("val1"); | ||
Assertions.assertThat(aliasMap.containsKey("param")).isTrue(); | ||
} | ||
|
||
@Test | ||
public void testAliasAKernelParam() throws Exception | ||
{ | ||
AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("alias", "val1"); | ||
aliasMap.putAlias("alias", "param"); | ||
|
||
Assertions.assertThat(aliasMap.get("param")).isEqualTo("val1"); | ||
Assertions.assertThat(aliasMap.containsAllKeys(Lists.newArrayList("param", "alias"))).isTrue(); | ||
} | ||
|
||
@Test | ||
public void testCannotAliasAnExistingParameter() throws Exception | ||
{ | ||
AliasMap aliasMap = new AliasMap(); | ||
try | ||
{ | ||
aliasMap.put("param", "val1"); | ||
aliasMap.putAlias("alias", "param"); | ||
} catch (IllegalArgumentException e) | ||
{ | ||
Assertions.assertThat(e).hasMessage("The key \"param\" to alias is already present in the kernel parameters."); | ||
|
||
Assertions.assertThat(aliasMap.containsKey("param")).isTrue(); | ||
} | ||
} | ||
|
||
@Test | ||
public void testContainsKey() throws Exception | ||
{ | ||
AliasMap aliasMap = new AliasMap(); | ||
Assertions.assertThat(aliasMap.containsKey("foo")).isFalse(); | ||
Assertions.assertThat(aliasMap.containsAllKeys(Lists.newArrayList("foo", "bar"))).isFalse(); | ||
} | ||
|
||
@Test | ||
public void testComputedMapNotNull() throws Exception | ||
{ | ||
Assertions.assertThat(new AliasMap().toMap()).isNotNull(); | ||
} | ||
|
||
@Test | ||
public void testComputedMapContainsParameters() throws Exception | ||
{ | ||
final AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("param1", "val1"); | ||
aliasMap.put("param2", "val2"); | ||
Assertions.assertThat(aliasMap.toMap()).containsExactly(entry("param1", "val1"), entry("param2", "val2")); | ||
} | ||
|
||
@Test | ||
public void testComputedMapContainsAlias() throws Exception | ||
{ | ||
final AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("alias1", "val1"); | ||
aliasMap.put("alias2", "val2"); | ||
aliasMap.putAlias("alias1", "param1"); | ||
aliasMap.putAlias("alias2", "param2"); | ||
Assertions.assertThat(aliasMap.toMap()) | ||
.containsOnly( | ||
entry("param1", "val1"), | ||
entry("param2", "val2"), | ||
entry("alias1", "val1"), | ||
entry("alias2", "val2") | ||
); | ||
} | ||
|
||
@Test | ||
public void testMultipleAliasIndirection() throws Exception | ||
{ | ||
final AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("alias2", "val1"); | ||
aliasMap.putAlias("alias1", "param1"); | ||
aliasMap.putAlias("alias2", "alias1"); | ||
Assertions.assertThat(aliasMap.toMap()) | ||
.containsOnly( | ||
entry("param1", "val1"), | ||
entry("alias1", "val1"), | ||
entry("alias2", "val1") | ||
); | ||
} | ||
|
||
@Test | ||
public void testInfiniteIndirection() throws Exception | ||
{ | ||
final AliasMap aliasMap = new AliasMap(); | ||
aliasMap.put("alias1", "val1"); | ||
aliasMap.putAlias("alias1", "param1"); | ||
aliasMap.putAlias("param1", "alias1"); | ||
try | ||
{ | ||
aliasMap.toMap(); | ||
} catch (KernelException e) | ||
{ | ||
Assertions.assertThat(e).hasMessage("Cycle detected in kernel parameter aliases."); | ||
} | ||
} | ||
|
||
@Test(expected = UnsupportedOperationException.class) | ||
public void testComputedMapIsImmutable() throws Exception | ||
{ | ||
new AliasMap().toMap().put("foo", "bar"); | ||
Assertions.fail("The map should be immutable"); | ||
} | ||
} |
Oops, something went wrong.