Search in sources :

Example 1 with ClassAlreadyExistsException

use of org.jsonschema2pojo.exception.ClassAlreadyExistsException in project jsonschema2pojo by joelittlejohn.

the class ObjectRule method apply.

/**
 * Applies this schema rule to take the required code generation steps.
 * <p>
 * When this rule is applied for schemas of type object, the properties of
 * the schema are used to generate a new Java class and determine its
 * characteristics. See other implementers of {@link Rule} for details.
 */
@Override
public JType apply(String nodeName, JsonNode node, JsonNode parent, JPackage _package, Schema schema) {
    JType superType = reflectionHelper.getSuperType(nodeName, node, _package, schema);
    if (superType.isPrimitive() || reflectionHelper.isFinal(superType)) {
        return superType;
    }
    JDefinedClass jclass;
    try {
        jclass = createClass(nodeName, node, _package);
    } catch (ClassAlreadyExistsException e) {
        return e.getExistingClass();
    }
    jclass._extends((JClass) superType);
    schema.setJavaTypeIfEmpty(jclass);
    if (node.has("title")) {
        ruleFactory.getTitleRule().apply(nodeName, node.get("title"), node, jclass, schema);
    }
    if (node.has("description")) {
        ruleFactory.getDescriptionRule().apply(nodeName, node.get("description"), node, jclass, schema);
    }
    if (node.has("$comment")) {
        ruleFactory.getCommentRule().apply(nodeName, node.get("$comment"), node, jclass, schema);
    }
    // Creates the class definition for the builder
    if (ruleFactory.getGenerationConfig().isGenerateBuilders() && ruleFactory.getGenerationConfig().isUseInnerClassBuilders()) {
        ruleFactory.getBuilderRule().apply(nodeName, node, parent, jclass, schema);
    }
    ruleFactory.getPropertiesRule().apply(nodeName, node.get("properties"), node, jclass, schema);
    if (node.has("javaInterfaces")) {
        addInterfaces(jclass, node.get("javaInterfaces"));
    }
    ruleFactory.getAdditionalPropertiesRule().apply(nodeName, node.get("additionalProperties"), node, jclass, schema);
    ruleFactory.getDynamicPropertiesRule().apply(nodeName, node.get("properties"), node, jclass, schema);
    if (node.has("required")) {
        ruleFactory.getRequiredArrayRule().apply(nodeName, node.get("required"), node, jclass, schema);
    }
    if (ruleFactory.getGenerationConfig().isIncludeGeneratedAnnotation()) {
        AnnotationHelper.addGeneratedAnnotation(jclass);
    }
    if (ruleFactory.getGenerationConfig().isIncludeToString()) {
        addToString(jclass);
    }
    if (ruleFactory.getGenerationConfig().isIncludeHashcodeAndEquals()) {
        addHashCode(jclass, node);
        addEquals(jclass, node);
    }
    if (ruleFactory.getGenerationConfig().isParcelable()) {
        addParcelSupport(jclass);
    }
    if (ruleFactory.getGenerationConfig().isIncludeConstructors()) {
        ruleFactory.getConstructorRule().apply(nodeName, node, parent, jclass, schema);
    }
    if (ruleFactory.getGenerationConfig().isSerializable()) {
        SerializableHelper.addSerializableSupport(jclass);
    }
    return jclass;
}
Also used : JDefinedClass(com.sun.codemodel.JDefinedClass) JType(com.sun.codemodel.JType) JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) ClassAlreadyExistsException(org.jsonschema2pojo.exception.ClassAlreadyExistsException)

Example 2 with ClassAlreadyExistsException

use of org.jsonschema2pojo.exception.ClassAlreadyExistsException in project jsonschema2pojo by joelittlejohn.

the class ObjectRule method createClass.

/**
 * Creates a new Java class that will be generated.
 *
 * @param nodeName
 *            the node name which may be used to dictate the new class name
 * @param node
 *            the node representing the schema that caused the need for a
 *            new class. This node may include a 'javaType' property which
 *            if present will override the fully qualified name of the newly
 *            generated class.
 * @param _package
 *            the package which may contain a new class after this method
 *            call
 * @return a reference to a newly created class
 * @throws ClassAlreadyExistsException
 *             if the given arguments cause an attempt to create a class
 *             that already exists, either on the classpath or in the
 *             current map of classes to be generated.
 */
private JDefinedClass createClass(String nodeName, JsonNode node, JPackage _package) throws ClassAlreadyExistsException {
    JDefinedClass newType;
    Annotator annotator = ruleFactory.getAnnotator();
    try {
        if (node.has("existingJavaType")) {
            String fqn = substringBefore(node.get("existingJavaType").asText(), "<");
            if (isPrimitive(fqn, _package.owner())) {
                throw new ClassAlreadyExistsException(primitiveType(fqn, _package.owner()));
            }
            JClass existingClass = resolveType(_package, fqn + (node.get("existingJavaType").asText().contains("<") ? "<" + substringAfter(node.get("existingJavaType").asText(), "<") : ""));
            throw new ClassAlreadyExistsException(existingClass);
        }
        boolean usePolymorphicDeserialization = annotator.isPolymorphicDeserializationSupported(node);
        if (node.has("javaType")) {
            String fqn = node.path("javaType").asText();
            if (isPrimitive(fqn, _package.owner())) {
                throw new GenerationException("javaType cannot refer to a primitive type (" + fqn + "), did you mean to use existingJavaType?");
            }
            if (fqn.contains("<")) {
                throw new GenerationException("javaType does not support generic args (" + fqn + "), did you mean to use existingJavaType?");
            }
            int index = fqn.lastIndexOf(".") + 1;
            if (index == 0) {
                // Actually not a fully qualified name
                fqn = _package.name() + "." + fqn;
                index = fqn.lastIndexOf(".") + 1;
            }
            if (index >= 0 && index < fqn.length()) {
                fqn = fqn.substring(0, index) + ruleFactory.getGenerationConfig().getClassNamePrefix() + fqn.substring(index) + ruleFactory.getGenerationConfig().getClassNameSuffix();
            }
            if (usePolymorphicDeserialization) {
                newType = _package.owner()._class(JMod.PUBLIC, fqn, ClassType.CLASS);
            } else {
                newType = _package.owner()._class(fqn);
            }
        } else {
            if (usePolymorphicDeserialization) {
                newType = _package._class(JMod.PUBLIC, ruleFactory.getNameHelper().getUniqueClassName(nodeName, node, _package), ClassType.CLASS);
            } else {
                newType = _package._class(ruleFactory.getNameHelper().getUniqueClassName(nodeName, node, _package));
            }
        }
    } catch (JClassAlreadyExistsException e) {
        throw new ClassAlreadyExistsException(e.getExistingClass());
    }
    annotator.typeInfo(newType, node);
    annotator.propertyInclusion(newType, node);
    return newType;
}
Also used : JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) JDefinedClass(com.sun.codemodel.JDefinedClass) Annotator(org.jsonschema2pojo.Annotator) JClass(com.sun.codemodel.JClass) GenerationException(org.jsonschema2pojo.exception.GenerationException) JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) ClassAlreadyExistsException(org.jsonschema2pojo.exception.ClassAlreadyExistsException)

Example 3 with ClassAlreadyExistsException

use of org.jsonschema2pojo.exception.ClassAlreadyExistsException in project jsonschema2pojo by joelittlejohn.

the class EnumRule method apply.

/**
 * Applies this schema rule to take the required code generation steps.
 * <p>
 * A Java {@link Enum} is created, with constants for each of the enum
 * values present in the schema. The enum name is derived from the nodeName,
 * and the enum type itself is created as an inner class of the owning type.
 * In the rare case that no owning type exists (the enum is the root of the
 * schema), then the enum becomes a public class in its own right.
 * <p>
 * The actual JSON value for each enum constant is held in a property called
 * "value" in the generated type. A static factory method
 * <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
 *            the enum node
 * @param parent
 *            the parent node
 * @param container
 *            the class container (class or package) to which this enum
 *            should be added
 * @return the newly generated Java type that was created to represent the
 *         given enum
 */
@Override
public JType apply(String nodeName, JsonNode node, JsonNode parent, JClassContainer container, Schema schema) {
    if (node.has("existingJavaType")) {
        JType type = ruleFactory.getTypeRule().apply(nodeName, node, parent, container.getPackage(), schema);
        schema.setJavaTypeIfEmpty(type);
        return type;
    }
    JDefinedClass _enum;
    try {
        _enum = createEnum(node, nodeName, container);
    } catch (ClassAlreadyExistsException e) {
        ruleFactory.getLogger().error("Could not create enum.", e);
        return e.getExistingClass();
    }
    schema.setJavaTypeIfEmpty(_enum);
    // Add JavaDocs
    if (node.has("title")) {
        ruleFactory.getTitleRule().apply(nodeName, node.get("title"), node, _enum, schema);
    }
    if (node.has("description")) {
        ruleFactory.getDescriptionRule().apply(nodeName, node.get("description"), node, _enum, schema);
    }
    if (node.has("$comment")) {
        ruleFactory.getCommentRule().apply(nodeName, node.get("$comment"), node, _enum, schema);
    }
    if (node.has("javaInterfaces")) {
        addInterfaces(_enum, node.get("javaInterfaces"));
    }
    // copy our node; remove the javaType as it will throw off the TypeRule for our case
    ObjectNode typeNode = (ObjectNode) node.deepCopy();
    typeNode.remove("javaType");
    // If type is specified on the enum, get a type rule for it.  Otherwise, we're a string.
    // (This is different from the default of Object, which is why we don't do this for every case.)
    JType backingType = node.has("type") ? ruleFactory.getTypeRule().apply(nodeName, typeNode, parent, container, schema) : container.owner().ref(String.class);
    EnumDefinition enumDefinition = buildEnumDefinition(nodeName, node, backingType);
    if (ruleFactory.getGenerationConfig() != null && ruleFactory.getGenerationConfig().isIncludeGeneratedAnnotation()) {
        AnnotationHelper.addGeneratedAnnotation(_enum);
    }
    JFieldVar valueField = addConstructorAndFields(enumDefinition, _enum);
    // override toString only if we have a sensible string to return
    if (isString(backingType)) {
        addToString(_enum, valueField);
    }
    addFieldAccessors(_enum, valueField);
    addEnumConstants(enumDefinition, _enum, schema);
    addFactoryMethod(enumDefinition, _enum);
    applyCustomizations(enumDefinition, _enum);
    return _enum;
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) JDefinedClass(com.sun.codemodel.JDefinedClass) JFieldVar(com.sun.codemodel.JFieldVar) EnumDefinition(org.jsonschema2pojo.model.EnumDefinition) JType(com.sun.codemodel.JType) JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) ClassAlreadyExistsException(org.jsonschema2pojo.exception.ClassAlreadyExistsException)

Aggregations

JClassAlreadyExistsException (com.sun.codemodel.JClassAlreadyExistsException)3 JDefinedClass (com.sun.codemodel.JDefinedClass)3 ClassAlreadyExistsException (org.jsonschema2pojo.exception.ClassAlreadyExistsException)3 JType (com.sun.codemodel.JType)2 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)1 JClass (com.sun.codemodel.JClass)1 JFieldVar (com.sun.codemodel.JFieldVar)1 Annotator (org.jsonschema2pojo.Annotator)1 GenerationException (org.jsonschema2pojo.exception.GenerationException)1 EnumDefinition (org.jsonschema2pojo.model.EnumDefinition)1