/** * Checks if a type is an descendant of an other type * @param item The base type. * @param candidate The candidate type. * @return true if candidate is a descendant of base type. */ public static boolean isDescendant(JavaType item, JavaType candidate) { if (item == null || candidate == null) { return false; } else if (item.equals(candidate)) { return true; } else if (isDescendant(item.getSuperClass(), candidate)) { return true; } else { for (JavaType interfaceType : item.getInterfaces()) { if (isDescendant(interfaceType, candidate)) { return true; } } return false; } }
public static boolean isGeneric(JavaType type) { return type.getAttributes().containsKey(IS_GENERIC) && (type.getAttributes().get(IS_GENERIC) instanceof Boolean) && (Boolean) type.getAttributes().get(IS_GENERIC); } }
public JavaType apply(JavaType item) { List<JavaType> generics = new ArrayList<JavaType>(); for (JavaType generic : item.getGenericTypes()) { generics.add(generic); } generics.add(Constants.T); return new JavaTypeBuilder(item) .withClassName(item.getClassName() + "Fluent") .withGenericTypes(generics.toArray(new JavaType[generics.size()])) .build(); } },
public JavaType apply(JavaType type) { if (type.isCollection()) { return type.getGenericTypes()[0]; } else { return type; } }
public static boolean isSet(JavaType type) { return type.equals(SET) || type.getInterfaces().contains(SET); } }
@Override public JavaType apply(String fullName) { JavaType type = delegate.apply(fullName); if (type == null) { return null; } TypeElement typeElement = elements.getTypeElement(fullName); boolean isBuildable = false; if (fullName.endsWith("[]")) { typeElement = elements.getTypeElement(fullName.substring(0, fullName.length() - 2)); isBuildable = isBuildable(typeElement); } else if (type.isCollection()) { for (JavaType genericType : type.getGenericTypes()) { isBuildable = isBuildable(elements.getTypeElement(genericType.getFullyQualifiedName())); } } else { isBuildable = isBuildable(typeElement); } Map<String, Object> attributes = new HashMap<String, Object>(type.getAttributes()); attributes.put(BUILDABLE, isBuildable); return new JavaTypeBuilder(type).withAttributes(attributes).build(); }
@Override public JavaMethod apply(JavaProperty property) { String builderName = TypeAs.UNWRAP_COLLECTION_OF.apply(property.getType()).getSimpleName("Builder"); String classPrefix = getClassPrefix(property); String prefix = property.getType().isCollection() ? "addTo" : "with"; String withMethodName = prefix + captializeFirst(property.getName()); return new JavaMethodBuilder() .addToModifiers(Modifier.PUBLIC) .withReturnType(N) .withName("and") .addToAttributes(BODY, "return (N) " + classPrefix + withMethodName + "(builder.build());") .build(); }
@Override public JavaType apply(JavaType item) { BuilderContext ctx = BuilderContextManager.getContext(); JavaType fluent = SHALLOW_FLUENT.apply(item); List<JavaType> generics = new ArrayList<JavaType>(); for (JavaType generic : item.getGenericTypes()) { generics.add(generic); } JavaType generic = typeExtends(Constants.T, fluent); generics.add(generic); JavaType superClass = isBuildable(item.getSuperClass()) ? SHALLOW_FLUENT.apply(item.getSuperClass()) : ctx.getBaseFluentClass().getType(); return new JavaTypeBuilder(item) .withClassName(item.getClassName() + "Fluent") .withPackageName(item.getPackageName()) .withGenericTypes(generics.toArray(new JavaType[generics.size()])) .withSuperClass(superClass) .withInterfaces(new HashSet(Arrays.asList(ctx.getFluentInterface().getType()))) .build(); }
public JavaType apply(JavaType type) { Set<JavaType> interfaces = new LinkedHashSet<JavaType>(); Set<JavaType> generics = new LinkedHashSet<JavaType>(); if (GENERIC_MAPPINGS.containsValue(type)) { JavaType unmapped = UNMAP.apply(type); if (!unmapped.equals(type)) { return UNWRAP.apply(unmapped); } return unmapped; } else { for (JavaType iface : type.getInterfaces()) { interfaces.add(UNWRAP.apply(iface)); } for (JavaType generic : type.getGenericTypes()) { generics.add(UNWRAP.apply(generic)); } return new JavaTypeBuilder(type) .withGenericTypes(generics.toArray(new JavaType[generics.size()])) .withInterfaces(interfaces) .build(); } } };
private String getBody(JavaProperty property) { String name = property.getName(); JavaType type = property.getType(); String className = type.getClassName(); StringBuilder sb = new StringBuilder(); if (type.isCollection()) { sb.append("this." + name + ".clear();"); if (className.contains("Map")) { sb.append("if (" + name + " != null) {this." + name + ".putAll(" + name + ");} return (T) this;"); } else if (className.contains("List") || className.contains("Set")) { JavaType unwraped = TypeAs.UNWRAP_COLLECTION_OF.apply(property.getType()); String addToMethodName = "addTo" + property.getNameCapitalized(); sb.append("if (" + name + " != null) {for (" + unwraped.getSimpleName() + " item : " + name + "){this." + addToMethodName + "(item);}} return (T) this;"); } return sb.toString(); } else if (isBuildable(property)) { JavaType builder = combine(UNWRAP_COLLECTION_OF, BUILDER).apply(property.getType()); String propertyName = property.getName(); String builderClass = builder.getSimpleName(); return "if (" + propertyName + "!=null){ this." + propertyName + "= new " + builderClass + "(" + propertyName + "); _visitables.add(this." + propertyName + ");} return (T) this;"; } return "this." + property.getName() + "=" + property.getName() + "; return (T) this;"; }
@Override public JavaMethod apply(JavaProperty property) { String prefix = property.getType().isBoolean() ? "is" : "get"; String methodName = prefix + property.getNameCapitalized(); JavaType type = property.getType(); Boolean isBuildable = isBuildable(type); JavaType targetType = isBuildable ? VISITABLE_BUILDER.apply(type) : TypeAs.UNWRAP_ARRAY_OF.apply(type); String body = String.format(isBuildable ? BUILDABLE_ARRAY_GETTER_TEXT : SIMPLE_ARRAY_GETTER_TEXT,type.getClassName(), targetType.getSimpleName(), property.getName(), type.getClassName()); return new JavaMethodBuilder() .addToModifiers(Modifier.PUBLIC) .withName(methodName) .withReturnType(property.getType()) .withArguments(new JavaProperty[]{}) .addToAttributes(BODY, body) .build(); } },
public static boolean isPrimitive(JavaType type) { for (JavaType t :Constants.PRIMITIVE_TYPES) { if (type.getSimpleName().equals(t.getSimpleName())) { return true; } } return false; }
private static void popullateGenericTypes(JavaType type, Set<JavaType> result) { for (JavaType generic : type.getGenericTypes()) { popullateGenericTypes(generic, result); } result.add(type); }
private JavaType replaceGenericWith(JavaType source, JavaType from, JavaType to) { List<JavaType> generics = Arrays.asList(source.getGenericTypes()); if (generics.isEmpty()) { return source; } else if (source.equals(from)) { return to; } else { List<JavaType> updatedGenerics = new ArrayList<JavaType>(); for (JavaType generic : generics) { updatedGenerics.add(replaceGenericWith(generic, from, to)); } return new JavaTypeBuilder(source).withGenericTypes(updatedGenerics.toArray(new JavaType[generics.size()])).build(); } } }
private static String toEquals(JavaType type, Collection<JavaProperty> properties) { String simpleName = type.getClassName(); JavaType superClass = type.getSuperClass(); StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("if (this == o) return true;").append("\n"); sb.append("if (o == null || getClass() != o.getClass()) return false;").append("\n"); //If base fluent is the superclass just skip. if (!Constants.BASE_FLUENT.getClassName().equals(superClass.getClassName())) { sb.append("if (!super.equals(o)) return false;").append("\n"); } sb.append(simpleName).append(" that = (").append(simpleName).append(") o;").append("\n"); for (JavaProperty property : properties) { String name = property.getName(); if (BuilderUtils.isPrimitive(property.getType())) { sb.append("if (").append(name).append(" != ").append("that.").append(name).append(") return false;").append("\n"); } else if (BuilderUtils.isDescendant(type, property.getType())) { sb.append("if (").append(name).append(" != null &&").append(name).append(" != this ? !").append(name).append(".equals(that.").append(name).append(") :") .append("that.").append(name).append(" != null &&").append(name).append(" != this ) return false;").append("\n"); } else { sb.append("if (").append(name).append(" != null ? !").append(name).append(".equals(that.").append(name).append(") :") .append("that.").append(name).append(" != null) return false;").append("\n"); } } sb.append("return true;").append("\n"); return sb.toString(); }
@Override public JavaType apply(JavaType... items) { if (items == null || items.length == 0) { throw new IllegalArgumentException("Items cannot be empty."); } else if (items.length == 1) { return items[0]; } else if (items.length == 2) { JavaTypeBuilder builder = new JavaTypeBuilder(items[0]); for (JavaType type : items[1].getInterfaces()) { builder = builder.addToInterfaces(type); } for (JavaType type : items[1].getGenericTypes()) { if (!Arrays.asList(items[0].getGenericTypes()).contains(type)) { builder = builder.addToGenericTypes(type); } } return builder.build(); } else { JavaType[] rest = new JavaType[items.length - 1]; System.arraycopy(items, 1, rest, 0, rest.length); return TYPES.apply(new JavaType[]{items[0], TYPES.apply(rest)}); } } };
/** * Convert a {@link Collection} of {@link javax.lang.model.element.ExecutableElement}s to a {@link java.util.Set} of {@link io.sundr.codegen.model.JavaClazz}es. * * @param context The context of the operation. * @param elements The target elements. * @return A set of {@link io.sundr.codegen.model.JavaClazz} that describes the interfaces. */ public static Set<JavaClazz> executablesToInterfaces(DslProcessorContext context, Collection<ExecutableElement> elements) { Map<String, JavaClazz> byName = new LinkedHashMap<String, JavaClazz>(); for (ExecutableElement current : elements) { JavaClazz clazz = executableToInterface(context, current); InterfaceName interfaceName = current.getAnnotation(InterfaceName.class); String name = interfaceName != null ? clazz.getType().getPackageName() + "." + interfaceName.value() : clazz.getType().getFullyQualifiedName(); if (byName.containsKey(name)) { JavaClazz other = byName.remove(name); byName.put(name, Merge.CLASSES.apply(new JavaClazz[]{other, clazz})); } else { byName.put(name, clazz); } } return new LinkedHashSet<JavaClazz>(byName.values()); }
@Override public String apply(JavaType item) { return stripSuffix(item.getClassName()).substring(prefix.length()); } }, "Or"));
interfaces.add(alternative.getType()); terminatingTypes.addAll(getTerminatingTypes(alternative.getType())); for (JavaType candidate : alternative.getType().getGenericTypes()) { genericTypes.addAll(getGenericReferences(candidate)); interfaces.add(fallback.getType()); terminatingTypes.addAll(getTerminatingTypes(fallback.getType())); for (JavaType candidate : fallback.getType().getGenericTypes()) { genericTypes.addAll(getGenericReferences(candidate)); .withKind(JavaKind.INTERFACE) .withClassName(className) .withPackageName(interfaces.iterator().next().getPackageName()) .withInterfaces(interfaces) .withGenericTypes(genericTypes.toArray(new JavaType[genericTypes.size()]))
boolean buildable = (Boolean) toAdd.getType().getAttributes().get(BUILDABLE); if (toAdd.isArray()) { JavaProperty asList = arrayAsList(toAdd, buildable); methods.add(ToMethod.WITH_NEW_NESTED.apply(toAdd)); methods.add(ToMethod.WITH_NEW_LIKE_NESTED.apply(toAdd)); if (!toAdd.getType().isCollection() && !toAdd.isArray()) { methods.add(ToMethod.EDIT_NESTED.apply(toAdd)); if (toAdd.getType().isCollection()) { builderType = typeGenericOf(toAdd.getType(), builderType); } else if (descendants.size() > 0 && toAdd.getType().isCollection()) { properties.add(toAdd); if (descendant.getType().isCollection()) { methods.add(ToMethod.ADD_TO_COLLECTION.apply(descendant)); methods.add(ToMethod.REMOVE_FROM_COLLECTION.apply(descendant)); if (descendant.getType().isCollection()) { builderType = typeGenericOf(descendant.getType(), builderType);