Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintain order when using inline maps and lists #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/main/java/org/mvel2/ast/InlineCollectionNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import org.mvel2.util.CollectionParser;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -123,7 +123,7 @@ private void parseGraph(boolean compile, Class type, ParserContext pCtx) {

private Object execGraph(Object o, Class type, Object ctx, VariableResolverFactory factory) {
if (o instanceof List) {
ArrayList list = new ArrayList(((List) o).size());
LinkedList list = new LinkedList();

for (Object item : (List) o) {
list.add(execGraph(item, type, ctx, factory));
Expand All @@ -132,7 +132,7 @@ private Object execGraph(Object o, Class type, Object ctx, VariableResolverFacto
return list;
}
else if (o instanceof Map) {
HashMap map = new HashMap();
LinkedHashMap map = new LinkedHashMap();

for (Object item : ((Map) o).keySet()) {
map.put(execGraph(item, type, ctx, factory), execGraph(((Map) o).get(item), type, ctx, factory));
Expand Down
13 changes: 5 additions & 8 deletions src/main/java/org/mvel2/util/CollectionParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import org.mvel2.ParserContext;
import org.mvel2.compiler.ExecutableStatement;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static org.mvel2.util.ParseTools.*;

Expand Down Expand Up @@ -94,7 +91,7 @@ public Object parseCollection(char[] property, int start, int offset, boolean su

private Object parseCollection(boolean subcompile) {
if (end - start == 0) {
if (type == LIST) return new ArrayList();
if (type == LIST) return new LinkedList();
else return EMPTY_ARRAY;
}

Expand All @@ -107,10 +104,10 @@ private Object parseCollection(boolean subcompile) {
switch (type) {
case ARRAY:
case LIST:
list = new ArrayList<Object>();
list = new LinkedList<Object>();
break;
case MAP:
map = new HashMap<Object, Object>();
map = new LinkedHashMap<Object, Object>();
break;
}
}
Expand Down Expand Up @@ -188,7 +185,7 @@ else if (cursor < end) {

case ':':
if (type != MAP) {
map = new HashMap<Object, Object>();
map = new LinkedHashMap<Object, Object>();
type = MAP;
}
curr = createStringTrimmed(property, st, cursor - st);
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/org/mvel2/tests/core/InlineCollectionsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.LinkedHashSet;

public class InlineCollectionsTests extends AbstractTest {
public void testListCreation2() {
Expand Down Expand Up @@ -360,4 +362,40 @@ public void testElementToList() {
}


public void testInlineCollectionOrderOfKeys() {

Set<String> keys = new LinkedHashSet<String>();
keys.add("a");
keys.add("b");
keys.add("c");
keys.add("d");
keys.add("e");

String mvelSource = "[ 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 ]";
Map eval = (Map) MVEL.eval(mvelSource);

assertTrue(hasSameOrder(keys, eval.keySet()));
}

private Boolean hasSameOrder(Set<String> a, Set<String> b) {

// Check if they have same values
if (!a.equals(b)) {
return false;
}

String[] aArray = a.toArray(new String[a.size()]);
String[] bArray = b.toArray(new String[b.size()]);

// Check keys to make sure order is the same
for (int i=0; i < aArray.length; i ++) {
if (!aArray[i].equals(bArray[i])) {
return false;
}
}

return true;
}


}