1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.parser;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.LinkedHashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 public class ASTSwitchStatement extends JexlNode {
26
27
28
29 protected boolean isStatement = true;
30
31
32
33 protected Map<Object, Integer> cases = Collections.emptyMap();
34
35 public ASTSwitchStatement(final int id) {
36 super(id);
37 }
38
39 @Override
40 public Object jjtAccept(final ParserVisitor visitor, final Object data) {
41 return visitor.visit(this, data);
42 }
43
44
45
46
47
48
49
50
51
52 public List<Object>[] getCasesList() {
53 @SuppressWarnings("unchecked")
54 final List<Object>[] list = new List[jjtGetNumChildren() -1];
55 for (final Map.Entry<Object, Integer> entry : cases.entrySet()) {
56 final int index = entry.getValue();
57 if (index < 0 || index >= list.length) {
58 throw new IndexOutOfBoundsException("switch index out of bounds: " + index);
59 }
60 List<Object> values = list[index];
61 if (values == null) {
62 list[index] = values = new ArrayList<>();
63 }
64 values.add(entry.getValue());
65 }
66 return list;
67 }
68
69 public boolean isStatement() {
70 return isStatement;
71 }
72
73 public int switchIndex(final Object value) {
74 final Object code = JexlParser.switchCode(value);
75 Integer index = cases.get(code);
76 if (index == null) {
77 index = cases.get(JexlParser.DFLT);
78 }
79 if (index != null && index >= 1 && index < jjtGetNumChildren()) {
80 return index;
81 }
82 return -1;
83 }
84
85
86
87
88
89 public static class Helper {
90 private int switchIndex = 1;
91 private boolean defaultDefined;
92 private final Map<Object, Integer> dispatch = new LinkedHashMap<>();
93
94 void defineCase(final JexlParser.SwitchSet switchSet) throws ParseException {
95 if (switchSet.isEmpty()) {
96 if (defaultDefined) {
97 throw new ParseException("default clause is already defined");
98 }
99 defaultDefined = true;
100 dispatch.put(JexlParser.DFLT, switchIndex);
101 } else {
102 for (final Object constant : switchSet) {
103 if (dispatch.put(constant == null ? JexlParser.NIL : constant, switchIndex) != null) {
104 throw new ParseException("duplicate case in switch statement for value: " + constant);
105 }
106 }
107 switchSet.clear();
108 }
109 switchIndex += 1;
110 }
111
112 void defineSwitch(final ASTSwitchStatement statement) {
113 statement.cases = dispatch;
114 }
115 }
116
117 }