├── LICENSE
├── README.md
├── file.csv
├── file.java
├── out
└── artifacts
│ └── CsvEnumGenerator_jar
│ ├── CsvEnumGenerator.jar
│ ├── countries.csv
│ └── countries.java
├── pom.xml
└── src
├── META-INF
└── MANIFEST.MF
└── com
└── danesisinni
├── CSVEnumGenerator.java
└── Main.java
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Dane Sisinni
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Java Enum Generator - from CSV files
2 | Generates java Enums from CSV files
3 |
4 | ## Goals
5 | * enables seamless generation of Java enums for large datasets
6 |
7 | ## Formating the CSV file
8 | * the CSV file must be properly formatted in order for the generator to run properly
9 | * the first line of the CSV consists of all the variable types/names
10 | * one of the header cells must contain the word `VALUE` which indicates the column is reserved for the enum constant names
11 | * example header: `VALUE,String country,String code`
12 |
13 | ## Running from the Command Line
14 | * The jar file is located in `out/artificats/CsvEnumGenerator_jar`
15 | * Argument Ordering:
16 | 1. CSV file to read from
17 | 2. Name of the enum
18 | 3. output file
19 | * Running the generator from the command line: `java -jar CsvEnumGenerator.jar csvFile.csv ENUMNAME enumname.java`
20 | * if using Intellij use `Ctrl+Alt+L` to reformat the enum source code
21 |
22 | ## Sample parseable CSV
23 | ```csv
24 | VALUE,String countryName,String alpha2,String alpha3
25 | CANADA,Canada,CA,CAN
26 | UNITED_STATES,United States,US,USA
27 | ```
28 | * aside from the reserved `VALUE` cell header, all other headers must contain a space to separate the variable type and variable name
29 |
30 | ## Generating with custom data types
31 | * whenever a custom data type is used simply create an additional constructor after the enum is generated that parses the String and converts it to the specified object type
32 |
33 | #### Custom data type example
34 | ```csv
35 | VALUE,String countryName,LocalDate foundedOn
36 | CANADA,Canada,1867-07-01
37 | UNITED_STATES,United States of America,1776-07-04
38 | ```
39 | ##### Generated Enum: `java -jar CsvEnumGenerator.jar countries.csv COUNTRY countries.java`
40 | ```java
41 | public enum COUNTRY {
42 |
43 | CANADA("Canada","1867-07-01"),
44 | UNITED_STATES("United States Of America","1776-07-04");
45 |
46 | private final String countryName;
47 | private final LocalDate foundedOn;
48 |
49 |
50 | COUNTRY(String countryName,LocalDate foundedOn) {
51 | this.countryName = countryName;
52 | this.foundedOn = foundedOn;
53 | }
54 |
55 | public String getCountryName() {
56 | return this.countryName;
57 | }
58 |
59 | public LocalDate getFoundedOn() {
60 | return this.foundedOn;
61 | }
62 | }
63 | ```
64 |
65 | ##### Code to add:
66 | ```java
67 | private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
68 |
69 | COUNTRY(String countryName, String foundedOn) {
70 | LocalDate date = LocalDate.parse(foundedOn, formatter);
71 | this(countryName, date);
72 | }
73 | ```
74 | * As you can see for large data sets the csv-enum generator will signficantly reduce the manual work/number of lines a developer has to write
75 |
76 | ## Technologies Used
77 | * Java 8
78 | * Maven
79 | * Guava
80 | * Lombok
81 | * Apache Commons Lang
82 | * Apache Commons CSV
83 |
84 | Please feel free to reach out if there are any improvements that can be made or if you have any questions :)
85 |
--------------------------------------------------------------------------------
/file.csv:
--------------------------------------------------------------------------------
1 | VALUE,String x,int y,LocalDateTime blob
2 | CANADA,canada,1,2014-05-07 14:23
3 | USA,null,2,null
4 |
--------------------------------------------------------------------------------
/file.java:
--------------------------------------------------------------------------------
1 | public enum NAME {
2 |
3 | CANADA("2014-05-07 14:23","canada",1),
4 | USA(null,null,2);
5 |
6 | private final LocalDateTime blob;
7 | private final String x;
8 | private final int y;
9 |
10 |
11 | NAME(LocalDateTime blob,String x,int y) {
12 | this.blob = blob;
13 | this.x = x;
14 | this.y = y
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/out/artifacts/CsvEnumGenerator_jar/CsvEnumGenerator.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfsisinni/enum-generator-from-csv-java/fb8b561047df8c3f3b13bd3f3276448995ac04ee/out/artifacts/CsvEnumGenerator_jar/CsvEnumGenerator.jar
--------------------------------------------------------------------------------
/out/artifacts/CsvEnumGenerator_jar/countries.csv:
--------------------------------------------------------------------------------
1 | VALUE,String countryName,LocalDate foundedOn
2 | CANADA,Canada,1867-07-01
3 | UNITED_STATES,United States Of America,1776-07-04
4 |
--------------------------------------------------------------------------------
/out/artifacts/CsvEnumGenerator_jar/countries.java:
--------------------------------------------------------------------------------
1 | public enum COUNTRY {
2 |
3 | CANADA("1867-07-01","Canada"),
4 | UNITED_STATES("1776-07-04","United States Of America");
5 |
6 | private final LocalDate foundedOn;
7 | private final String countryName;
8 |
9 |
10 | COUNTRY(LocalDate foundedOn,String countryName) {
11 | this.foundedOn = foundedOn;
12 | this.countryName = countryName;
13 | }
14 |
15 | public LocalDate getFoundedOn() {
16 | return this.foundedOn;
17 | }
18 |
19 | public String getCountryName() {
20 | return this.countryName;
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | CsvEnumGenerator
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 | org.apache.commons
14 | commons-csv
15 | 1.3
16 |
17 |
18 | org.projectlombok
19 | lombok
20 | 1.16.16
21 | provided
22 |
23 |
24 | com.google.guava
25 | guava
26 | 22.0
27 |
28 |
29 | org.apache.commons
30 | commons-lang3
31 | 3.6
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: com.danesisinni.Main
3 |
4 |
--------------------------------------------------------------------------------
/src/com/danesisinni/CSVEnumGenerator.java:
--------------------------------------------------------------------------------
1 | package com.danesisinni;
2 |
3 | import com.google.common.base.Joiner;
4 | import com.google.common.collect.ImmutableList;
5 | import com.google.common.collect.ImmutableMap;
6 | import com.google.common.collect.ImmutableSet;
7 | import lombok.AllArgsConstructor;
8 | import lombok.Data;
9 | import lombok.val;
10 | import org.apache.commons.csv.CSVFormat;
11 | import org.apache.commons.csv.CSVRecord;
12 | import org.apache.commons.lang3.StringUtils;
13 |
14 | import java.io.FileReader;
15 | import java.io.IOException;
16 | import java.util.ArrayList;
17 | import java.util.HashMap;
18 |
19 | public class CSVEnumGenerator {
20 |
21 | private static final String ENUM_INITIALIZATION_VALUE = "VALUE";
22 | private static final ImmutableSet NON_QUOTE_DATA_TYPES = new ImmutableSet.Builder()
23 | .add("int")
24 | .add("Integer")
25 | .add("long")
26 | .add("Long")
27 | .add("double")
28 | .add("Double")
29 | .add("Float")
30 | .add("float")
31 | .build();
32 |
33 | private final String CSV_FILE;
34 | private final String ENUM_NAME;
35 |
36 | public CSVEnumGenerator(String CSV_FILE, String ENUM_NAME) {
37 | this.CSV_FILE = CSV_FILE;
38 | this.ENUM_NAME = ENUM_NAME;
39 | }
40 |
41 | public String getEnum() {
42 | val enumWrapper = getDataFromCSVFile();
43 |
44 | val enumBuilder = new StringBuilder();
45 | enumBuilder.append("public enum ");
46 | enumBuilder.append(ENUM_NAME);
47 | enumBuilder.append(" { \n\n");
48 |
49 | val arguments = enumWrapper.getDataTypes();
50 | val argumentOrder = arguments.keySet().asList();
51 |
52 |
53 | val initializationList = new ArrayList();
54 | for (EnumData entry : enumWrapper.getEnumData()) {
55 | val instanceBuilder = new StringBuilder();
56 | instanceBuilder.append(entry.getName());
57 | instanceBuilder.append("(");
58 |
59 | val paramsList = new ArrayList();
60 | for (String argument : argumentOrder) {
61 | val arg = entry.getInitializationValues().get(argument);
62 | if (needsQuotes(arguments.get(argument), arg)) {
63 | paramsList.add("\"" + arg + "\"");
64 | } else {
65 | paramsList.add(arg);
66 | }
67 | }
68 | instanceBuilder.append(Joiner.on(",").join(paramsList));
69 | instanceBuilder.append(")");
70 | initializationList.add(instanceBuilder.toString());
71 | }
72 |
73 | enumBuilder.append(Joiner.on(",\n").join(initializationList));
74 | enumBuilder.append(";\n\n");
75 |
76 | for (String argument : argumentOrder) {
77 | enumBuilder.append("private final ");
78 | enumBuilder.append(arguments.get(argument));
79 | enumBuilder.append(" ");
80 | enumBuilder.append(argument);
81 | enumBuilder.append(";\n");
82 | }
83 |
84 | enumBuilder.append("\n\n");
85 | enumBuilder.append(ENUM_NAME);
86 | enumBuilder.append("(");
87 |
88 | val parameters = new ArrayList();
89 | for (String argument : argumentOrder) {
90 | parameters.add(arguments.get(argument) + " " + argument);
91 | }
92 | enumBuilder.append(Joiner.on(",").join(parameters));
93 | enumBuilder.append(") {\n");
94 |
95 | val initialize = new ArrayList();
96 | for (String argument : argumentOrder) {
97 | initialize.add("this." + argument + " = " + argument + ";");
98 | }
99 | enumBuilder.append(Joiner.on("\n").join(initialize));
100 | enumBuilder.append("\n}\n\n");
101 |
102 |
103 | for (String argument : argumentOrder) {
104 | enumBuilder.append("public ");
105 | enumBuilder.append(arguments.get(argument));
106 | enumBuilder.append(" get");
107 | enumBuilder.append(StringUtils.capitalize(argument));
108 | enumBuilder.append("() {\n");
109 | enumBuilder.append("return this.");
110 | enumBuilder.append(argument);
111 | enumBuilder.append(";\n}\n\n");
112 | }
113 |
114 | enumBuilder.append("}");
115 |
116 | return enumBuilder.toString();
117 | }
118 |
119 | private boolean needsQuotes(String dataType, String value) {
120 | return !(value.equals("null") || NON_QUOTE_DATA_TYPES.contains(dataType));
121 | }
122 |
123 | private EnumWrapper getDataFromCSVFile() {
124 | final EnumWrapper data;
125 | try {
126 | data = getDataFromCSVFileThrowsException();
127 | } catch (IOException ex) {
128 | throw new IllegalStateException(String.format("Unable to parse file: %s", CSV_FILE), ex);
129 | }
130 | return data;
131 | }
132 |
133 | private EnumWrapper getDataFromCSVFileThrowsException() throws IOException {
134 | val data = new ArrayList();
135 | val fileReader = new FileReader(CSV_FILE);
136 | val records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(fileReader);
137 |
138 | val headerDataTypes = new HashMap();
139 | val headerMap = records.getHeaderMap();
140 |
141 | for (String header : headerMap.keySet()) {
142 | if (!header.trim().equals(ENUM_INITIALIZATION_VALUE)) {
143 | val split = header.trim().split(" ");
144 | if (split.length != 2) {
145 | throw new IllegalStateException(String.format("Invalid header: %s", header));
146 | }
147 |
148 | headerDataTypes.put(split[1], split[0]);
149 | }
150 | }
151 |
152 | for (CSVRecord record : records) {
153 | val entry = new HashMap();
154 | for (String header : headerMap.keySet()) {
155 | if (!header.trim().equals(ENUM_INITIALIZATION_VALUE)) {
156 | entry.put(header.trim().split(" ")[1], record.get(headerMap.get(header)));
157 | }
158 | }
159 | data.add(new EnumData(record.get(headerMap.get(ENUM_INITIALIZATION_VALUE)), ImmutableMap.copyOf(entry)));
160 | }
161 |
162 | return new EnumWrapper(ImmutableList.copyOf(data), ImmutableMap.copyOf(headerDataTypes));
163 | }
164 |
165 | @Data
166 | @AllArgsConstructor
167 | static class EnumWrapper {
168 | private ImmutableList enumData;
169 | private ImmutableMap dataTypes;
170 | }
171 |
172 | @Data
173 | @AllArgsConstructor
174 | static class EnumData {
175 |
176 | private String name;
177 | private ImmutableMap initializationValues;
178 |
179 | }
180 |
181 | }
182 |
--------------------------------------------------------------------------------
/src/com/danesisinni/Main.java:
--------------------------------------------------------------------------------
1 | package com.danesisinni;
2 |
3 | import lombok.val;
4 |
5 | import java.io.IOException;
6 | import java.nio.file.Files;
7 | import java.nio.file.Paths;
8 |
9 | public class Main {
10 |
11 | public static void main(String[] args) {
12 | String csvFile = "file.csv";
13 | String enumName = "NAME";
14 | String enumFile = "file.java";
15 |
16 | if (args.length == 3) {
17 | csvFile = args[0];
18 | enumName = args[1];
19 | enumFile = args[2];
20 | }
21 |
22 | CSVEnumGenerator generator = new CSVEnumGenerator(csvFile, enumName);
23 | val enumData = generator.getEnum();
24 | writeToFile(enumData, enumFile);
25 | }
26 |
27 | public static void writeToFile(String data, String fileName) {
28 | try {
29 | val path = Paths.get(fileName);
30 | Files.createFile(path);
31 | Files.write(path, data.getBytes());
32 | } catch (IOException e) {
33 | e.printStackTrace();
34 | }
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------