Skip to content

Commit

Permalink
Add javaEnumNames to allow custom names for enum constants
Browse files Browse the repository at this point in the history
Closes #385.
  • Loading branch information
joelittlejohn committed Aug 3, 2015
1 parent 4fa6132 commit 15bb26b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,36 @@

import javax.annotation.Generated;

import com.sun.codemodel.*;
import org.jsonschema2pojo.Schema;
import org.jsonschema2pojo.SchemaMapper;
import org.jsonschema2pojo.exception.ClassAlreadyExistsException;
import org.jsonschema2pojo.exception.GenerationException;

import com.fasterxml.jackson.databind.JsonNode;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JClassContainer;
import com.sun.codemodel.JConditional;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JEnumConstant;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JForEach;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;

/**
* Applies the "enum" schema rule.
*
* @see <a
* href="http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.19">http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.19</a>
*
* @see <a href=
* "http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.19">http:
* //tools.ietf.org/html/draft-zyp-json-schema-03#section-5.19</a>
*/
public class EnumRule implements Rule<JClassContainer, JType> {

Expand All @@ -66,7 +83,7 @@ protected EnumRule(RuleFactory ruleFactory) {
* <code>fromValue(String)</code> is added to the generated enum, and the
* methods are annotated to allow Jackson to marshal/unmarshal values
* correctly.
*
*
* @param nodeName
* the name of the property which is an "enum"
* @param node
Expand Down Expand Up @@ -96,7 +113,7 @@ public JType apply(String nodeName, JsonNode node, JClassContainer container, Sc

JFieldVar valueField = addValueField(_enum);
addToString(_enum, valueField);
addEnumConstants(node.path("enum"), _enum);
addEnumConstants(node.path("enum"), _enum, node.path("javaEnumNames"));
addFactoryMethod(_enum);

return _enum;
Expand Down Expand Up @@ -189,12 +206,12 @@ private void addToString(JDefinedClass _enum, JFieldVar valueField) {
toString.annotate(Override.class);
}

private void addEnumConstants(JsonNode node, JDefinedClass _enum) {
for (Iterator<JsonNode> values = node.elements(); values.hasNext();) {
JsonNode value = values.next();
private void addEnumConstants(JsonNode node, JDefinedClass _enum, JsonNode customNames) {
for (int i = 0; i < node.size(); i++) {
JsonNode value = node.path(i);

if (!value.isNull()) {
JEnumConstant constant = _enum.enumConstant(getConstantName(value.asText()));
JEnumConstant constant = _enum.enumConstant(getConstantName(value.asText(), customNames.path(i).asText()));
constant.arg(JExpr.lit(value.asText()));
ruleFactory.getAnnotator().enumConstant(constant, value.asText());
}
Expand Down Expand Up @@ -228,8 +245,11 @@ private String makeUnique(String className, JClassContainer container) {
return className;
}

protected String getConstantName(String nodeName, String customName) {
if (isNotBlank(customName)) {
return customName;
}

protected String getConstantName(String nodeName) {
List<String> enumNameGroups = new ArrayList<String>(asList(splitByCharacterTypeCamelCase(nodeName)));

String enumName = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public class EnumIT {
@SuppressWarnings("unchecked")
public static void generateAndCompileEnum() throws ClassNotFoundException {

ClassLoader resultsClassLoader = generateAndCompile("/schema/enum/typeWithEnumProperty.json", "com.example",
config("propertyWordDelimiters", "_"));
ClassLoader resultsClassLoader = generateAndCompile("/schema/enum/typeWithEnumProperty.json", "com.example", config("propertyWordDelimiters", "_"));

parentClass = resultsClassLoader.loadClass("com.example.TypeWithEnumProperty");
enumClass = (Class<Enum>) resultsClassLoader.loadClass("com.example.TypeWithEnumProperty$EnumProperty");
Expand Down Expand Up @@ -177,6 +176,34 @@ public void multipleEnumArraysWithSameName() throws ClassNotFoundException, NoSu
resultsClassLoader.loadClass("com.example.Status_");
}

@Test
@SuppressWarnings({ "unchecked" })
public void enumWithCustomJavaNames() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException {

ClassLoader resultsClassLoader = generateAndCompile("/schema/enum/enumWithCustomJavaNames.json", "com.example");

Class<?> typeWithEnumProperty = resultsClassLoader.loadClass("com.example.EnumWithCustomJavaNames");
Class<Enum> enumClass = (Class<Enum>) resultsClassLoader.loadClass("com.example.EnumWithCustomJavaNames$EnumProperty");

Object valueWithEnumProperty = typeWithEnumProperty.newInstance();
Method enumSetter = typeWithEnumProperty.getMethod("setEnumProperty", enumClass);
enumSetter.invoke(valueWithEnumProperty, enumClass.getEnumConstants()[2]);
assertThat(enumClass.getEnumConstants()[0].name(), is("ONE"));
assertThat(enumClass.getEnumConstants()[1].name(), is("TWO"));
assertThat(enumClass.getEnumConstants()[2].name(), is("THREE"));
assertThat(enumClass.getEnumConstants()[3].name(), is("FOUR"));

ObjectMapper objectMapper = new ObjectMapper();

String jsonString = objectMapper.writeValueAsString(valueWithEnumProperty);
JsonNode jsonTree = objectMapper.readTree(jsonString);

assertThat(jsonTree.size(), is(1));
assertThat(jsonTree.has("enum_Property"), is(true));
assertThat(jsonTree.get("enum_Property").isTextual(), is(true));
assertThat(jsonTree.get("enum_Property").asText(), is("3"));
}

@Test
@SuppressWarnings("unchecked")
public void jacksonCanMarshalEnums() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"type" : "object",
"properties" : {
"enum_Property" : {
"type" : "string",
"enum" : ["1", "2", "3", "4"],
"javaEnumNames" : ["ONE","TWO","THREE", "FOUR"]
}
}
}

0 comments on commit 15bb26b

Please sign in to comment.