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