Skip to content

Commit 435d510

Browse files
committed
add enum generation
1 parent 2236baf commit 435d510

4 files changed

Lines changed: 239 additions & 2 deletions

File tree

src/enum_generator.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
import re
2+
from dataclasses import dataclass
3+
from typing import List, Optional
4+
5+
from src.header_generator import set_package
6+
7+
8+
@dataclass
9+
class EnumClass:
10+
name: str
11+
values: List[str]
12+
description: Optional[str] = None
13+
14+
15+
indent_lvl1 = " "
16+
indent_lvl2 = indent_lvl1 * 2
17+
indent_lvl3 = indent_lvl1 * 3
218

319

420
def to_java_constant(value: str) -> str:
@@ -9,3 +25,116 @@ def to_java_constant(value: str) -> str:
925
value = re.sub(r"([0-9])([A-Za-z])", r"\1_\2", value) # 9a / 9A -> 9_A
1026

1127
return value.upper()
28+
29+
30+
def generate_enum_class(enum_class: EnumClass, package: str) -> str:
31+
enum_body = [
32+
set_package(package),
33+
"",
34+
f"import java.util.HashMap;",
35+
f"import java.util.Map;",
36+
f""
37+
]
38+
39+
enum_body.extend(_get_javadoc(enum_class.description))
40+
41+
enum_body.append(f"public enum {enum_class.name} {{")
42+
enum_body.extend(_get_constants(enum_class.values))
43+
44+
enum_body.append(f"")
45+
enum_body.append(f"{indent_lvl1}private final static Map<String, {enum_class.name}> CONSTANTS = new HashMap<String, {enum_class.name}>();")
46+
enum_body.append(f"")
47+
enum_body.extend(_get_static_method(enum_class.name))
48+
49+
enum_body.append(f"")
50+
enum_body.append(f"{indent_lvl1}private final String value;")
51+
enum_body.append(f"")
52+
enum_body.extend(_get_constructor(enum_class.name))
53+
54+
enum_body.append(f"")
55+
enum_body.extend(_get_fromValue_method(enum_class.name))
56+
57+
enum_body.append(f"")
58+
enum_body.extend(_get_toString_method())
59+
60+
enum_body.append(f"")
61+
enum_body.extend(_get_value_method())
62+
enum_body.append("}")
63+
enum_body.append(f"")
64+
65+
return "\n".join(enum_body)
66+
67+
68+
def _get_javadoc(description: str) -> List[str]:
69+
javadoc = [""]
70+
if description is not None:
71+
javadoc = [
72+
"",
73+
"/**",
74+
f" * {description}",
75+
" */"
76+
]
77+
return javadoc
78+
79+
80+
def _get_constants(constants: List[str]) -> List[str]:
81+
values = []
82+
for i, value in enumerate(constants):
83+
line_end = ";" if i == (len(constants) - 1) else ","
84+
values.append(
85+
f'{indent_lvl1}{to_java_constant(value)}("{value}"){line_end}'
86+
)
87+
return values
88+
89+
90+
def _get_static_method(class_name: str) -> List[str]:
91+
body = [
92+
f"{indent_lvl1}static {{",
93+
f"{indent_lvl2}for ({class_name} c : values()) {{",
94+
f"{indent_lvl3}CONSTANTS.put(c.value, c);",
95+
f"{indent_lvl2}}}",
96+
f"{indent_lvl1}}}"
97+
]
98+
return body
99+
100+
101+
def _get_constructor(class_name: str) -> List[str]:
102+
body = [
103+
f"{indent_lvl1}{class_name}(String value) {{",
104+
f"{indent_lvl2}this.value = value;",
105+
f"{indent_lvl1}}}"
106+
]
107+
return body
108+
109+
110+
def _get_fromValue_method(class_name: str) -> List[str]:
111+
body = [
112+
f"{indent_lvl1}public static {class_name} fromValue(String value) {{",
113+
f"{indent_lvl2}{class_name} constant = CONSTANTS.get(value);",
114+
f"{indent_lvl2}if (constant == null) {{",
115+
f"{indent_lvl3}throw new IllegalArgumentException(value);",
116+
f"{indent_lvl2}}} else {{",
117+
f"{indent_lvl3}return constant;",
118+
f"{indent_lvl2}}}",
119+
f"{indent_lvl1}}}"
120+
]
121+
return body
122+
123+
124+
def _get_toString_method() -> List[str]:
125+
body = [
126+
f"{indent_lvl1}@Override",
127+
f"{indent_lvl1}public String toString() {{",
128+
f"{indent_lvl2}return this.value;",
129+
f"{indent_lvl1}}}"
130+
]
131+
return body
132+
133+
134+
def _get_value_method() -> List[str]:
135+
body = [
136+
f"{indent_lvl1}public String value() {{",
137+
f"{indent_lvl2}return this.value;",
138+
f"{indent_lvl1}}}"
139+
]
140+
return body

tests/enum_reference_data.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from src.enum_generator import EnumClass
2+
3+
enum_AttributeEnum = EnumClass(
4+
name="AttributeEnum",
5+
values=["Actual", "Target", "MinSet", "MaxSet"],
6+
description="Type of attribute: Actual, Target, MinSet, MaxSet.")
7+
8+
enum_CancelReservationStatusEnum = EnumClass(
9+
name="CancelReservationStatusEnum",
10+
values=["Accepted"])
11+
12+
expected_AttributeEnum = """package ocpp.msgDef.Enumerations;
13+
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
17+
18+
/**
19+
* Type of attribute: Actual, Target, MinSet, MaxSet.
20+
*/
21+
public enum AttributeEnum {
22+
ACTUAL("Actual"),
23+
TARGET("Target"),
24+
MIN_SET("MinSet"),
25+
MAX_SET("MaxSet");
26+
27+
private final static Map<String, AttributeEnum> CONSTANTS = new HashMap<String, AttributeEnum>();
28+
29+
static {
30+
for (AttributeEnum c : values()) {
31+
CONSTANTS.put(c.value, c);
32+
}
33+
}
34+
35+
private final String value;
36+
37+
AttributeEnum(String value) {
38+
this.value = value;
39+
}
40+
41+
public static AttributeEnum fromValue(String value) {
42+
AttributeEnum constant = CONSTANTS.get(value);
43+
if (constant == null) {
44+
throw new IllegalArgumentException(value);
45+
} else {
46+
return constant;
47+
}
48+
}
49+
50+
@Override
51+
public String toString() {
52+
return this.value;
53+
}
54+
55+
public String value() {
56+
return this.value;
57+
}
58+
}
59+
"""
60+
61+
expected_CancelReservationStatusEnum = """package ocpp.anotherDef.Enums;
62+
63+
import java.util.HashMap;
64+
import java.util.Map;
65+
66+
67+
public enum CancelReservationStatusEnum {
68+
ACCEPTED("Accepted");
69+
70+
private final static Map<String, CancelReservationStatusEnum> CONSTANTS = new HashMap<String, CancelReservationStatusEnum>();
71+
72+
static {
73+
for (CancelReservationStatusEnum c : values()) {
74+
CONSTANTS.put(c.value, c);
75+
}
76+
}
77+
78+
private final String value;
79+
80+
CancelReservationStatusEnum(String value) {
81+
this.value = value;
82+
}
83+
84+
public static CancelReservationStatusEnum fromValue(String value) {
85+
CancelReservationStatusEnum constant = CONSTANTS.get(value);
86+
if (constant == null) {
87+
throw new IllegalArgumentException(value);
88+
} else {
89+
return constant;
90+
}
91+
}
92+
93+
@Override
94+
public String toString() {
95+
return this.value;
96+
}
97+
98+
public String value() {
99+
return this.value;
100+
}
101+
}
102+
"""

tests/reference_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@
3232
expected_setCustomData_CustomObject = """
3333
public void setCustomData(CustomObject customData) {
3434
this.customData = customData;
35-
}"""
35+
}"""

tests/test_enum_generator.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from src.enum_generator import to_java_constant
1+
from src.enum_generator import to_java_constant, generate_enum_class
2+
from tests.enum_reference_data import *
23

34

45
def test_to_java_constant():
@@ -21,3 +22,8 @@ def test_to_java_constant():
2122
}
2223
for key in values_expected.keys():
2324
assert to_java_constant(key) == values_expected[key]
25+
26+
27+
def test_generate_enum_class():
28+
assert generate_enum_class(enum_AttributeEnum, "ocpp.msgDef.Enumerations") == expected_AttributeEnum
29+
assert generate_enum_class(enum_CancelReservationStatusEnum, "ocpp.anotherDef.Enums") == expected_CancelReservationStatusEnum

0 commit comments

Comments
 (0)