public static JavaMethod findBuildableConstructor(JavaClazz clazz) { for (JavaMethod candidate : clazz.getConstructors()) { if (candidate.getArguments().length != 0) { return candidate; } } return clazz.getConstructors().iterator().next(); }
public static JavaMethod findGetter(JavaClazz clazz, JavaProperty property) { for (JavaMethod method : clazz.getMethods()) { if (isApplicableGetterOf(method, property)) { return method; } } return null; }
@Override public JavaClazz apply(JavaClazz... 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) { JavaType mergedType = TYPES.apply(new JavaType[]{items[0].getType(), items[1].getType()}); JavaClazzBuilder builder = new JavaClazzBuilder(items[0]).withType(mergedType); for (JavaMethod constructor : items[1].getConstructors()) { builder = builder.addToConstructors(constructor); } for (JavaMethod method : items[1].getMethods()) { builder = builder.addToMethods(method); } for (JavaProperty property : items[1].getFields()) { builder = builder.addToFields(property); } return builder.build(); } else { JavaClazz[] rest = new JavaClazz[items.length - 1]; System.arraycopy(items, 1, rest, 0, rest.length); CLASSES.apply(new JavaClazz[]{items[0], CLASSES.apply(rest)}); } return null; } };
JavaClazz inlineableOf(BuilderContext ctx, JavaClazz clazz, Inline inline) { JavaClazz base = ClazzAs.INLINEABLE.apply(clazz); JavaType baseInterface = typeGenericOf(BuilderUtils.getInlineType(ctx, inline), clazz.getType()); JavaMethod method = new JavaMethodBuilder(base.getMethods().iterator().next()).withName(inline.value()).build(); JavaType fluent = TypeAs.SHALLOW_FLUENT.apply(clazz.getType()); JavaType shallowInlineType = new JavaTypeBuilder(base.getType()) .withClassName(inline.prefix() + base.getType().getClassName() + inline.suffix()) .addToInterfaces(baseInterface) .build(); JavaType inlineType = new JavaTypeBuilder(shallowInlineType) .withSuperClass(typeGenericOf(fluent, shallowInlineType)) .build(); Set<JavaMethod> constructors = new LinkedHashSet<JavaMethod>(); for (JavaMethod constructor : base.getConstructors()) { constructors.add(new JavaMethodBuilder(constructor).withReturnType(inlineType).build()); } return new JavaClazzBuilder(base) .withType(inlineType) .withConstructors(constructors) .withMethods(new HashSet<JavaMethod>(Arrays.asList(method))) .build(); } }
@Override public JavaClazz apply(JavaClazz item) { JavaType type = item.getType(); JavaType editableType = TypeAs.EDITABLE.apply(type); JavaType builderType = TypeAs.BUILDER.apply(type); Set<JavaMethod> constructors = new LinkedHashSet<JavaMethod>(); Set<JavaMethod> methods = new LinkedHashSet<JavaMethod>(); for (JavaMethod constructor : item.getConstructors()) { constructors.add(superConstructorOf(constructor, editableType)); } JavaMethod edit = new JavaMethodBuilder() .withReturnType(builderType) .withName("edit") .addToAttributes(BODY, "return new " + builderType.getSimpleName() + "(this);") .build(); methods.add(edit); return new JavaClazzBuilder() .withType(editableType) .withConstructors(constructors) .withMethods(methods) .build(); } }, INLINEABLE {
for (Node<JavaClazz> root : graph) { JavaClazz current = root.getItem(); for (JavaMethod m : current.getMethods()) { methods.add(new JavaMethodBuilder(m).withReturnType(current.getType()).build());
/** * Checks if there is a default constructor available. * @param item The clazz to check. * @return */ public static boolean hasDefaultConstructor(JavaClazz item) { if (item == null) { return false; } else if (item.getConstructors().isEmpty()) { return true; } else { for (JavaMethod constructor : item.getConstructors()) { if (constructor.getArguments().length == 0) { return true; } } } return false; }
@Override public JavaClazz apply(JavaClazz item) { JavaClazz builder = BUILDER.apply(item); Set<JavaMethod> methods = new LinkedHashSet<JavaMethod>(); for (JavaMethod m : builder.getMethods()) { if (m.getName().equals("build")) { methods.add(new JavaMethodBuilder() .withReturnType(TypeAs.EDITABLE.apply(m.getReturnType())) .withName("build") .addToAttributes(BODY, toBuild(EDITABLE.apply(item))) .build()); } else { methods.add(m); } } return new JavaClazzBuilder(builder) .withMethods(methods) .build(); } }, EDITABLE {
public static Set<JavaMethod> getInlineableConstructors(JavaProperty property) { Set<JavaMethod> result = new HashSet<JavaMethod>(); JavaClazz clazz = PropertyAs.CLASS.apply(property); for (JavaMethod candidate : clazz.getConstructors()) { if (isInlineable(candidate)) { result.add(candidate); } } return result; }
@Override public String apply(JavaClazz item) { return item.getType().getSimpleName(); } }, "#");
private static Set<JavaClazz> exclusion(Set<JavaClazz> one, Set<JavaType> excluded) { Set<JavaClazz> result = new LinkedHashSet<JavaClazz>(); for (JavaClazz item : one) { if (!excluded.contains(item.getType()) || isTerminal(item) || isCardinalityMultiple(item)) { result.add(item); } } return result; }
private static boolean canBeExcluded(JavaClazz candidate, Iterable<JavaClazz> provided) { Set<JavaType> allOther = new LinkedHashSet<JavaType>(); for (JavaClazz c : provided) { if (!c.equals(candidate)) { allOther.addAll(JavaTypeUtils.extractInterfaces(c.getType())); } } Set<JavaType> allProvided = JavaTypeUtils.extractInterfaces(allOther); for (JavaType type : JavaTypeUtils.extractInterfaces(candidate.getType())) { if (!allProvided.contains(type)) { return false; } } return true; }
private static boolean isSatisfied(JavaClazz candidate, Set<JavaType> visited) { Set<String> visitedKeywords = getKeywords(visited); Boolean multiple = (Boolean) candidate.getType().getAttributes().get(CARDINALITY_MULTIPLE); Set<String> requiresAll = (Set<String>) candidate.getType().getAttributes().get(REQUIRES_ALL); Set<String> requiresAny = (Set<String>) candidate.getType().getAttributes().get(REQUIRES_ANY); Set<String> exclusive = (Set<String>) candidate.getType().getAttributes().get(EXCLUSIVE); //Eliminate circles if not supported if (!multiple && visited.contains(candidate.getType())) { return false; } //Check if path contains exclusive keywords for (String e : exclusive) { if (visitedKeywords.contains(e)) { return false; } } //Check if "All" requirements are meet for (String a : requiresAll) { if (!visitedKeywords.contains(a)) { return false; } } for (String a : requiresAny) { if (visitedKeywords.contains(a)) { return true; } } return requiresAny.isEmpty(); }
private static String toBuild(JavaClazz clazz) { JavaMethod constructor = findBuildableConstructor(clazz); StringBuilder sb = new StringBuilder(); sb.append(clazz.getType().getSimpleName()).append(" buildable = new ").append(clazz.getType().getSimpleName()).append("("); sb.append(StringUtils.join(constructor.getArguments(), new Function<JavaProperty, String>() { @Override public String apply(JavaProperty item) { String prefix = item.getType().isBoolean() ? "is" : "get"; return "fluent." + prefix + item.getNameCapitalized() + "()"; } }, ",")); sb.append(");\n"); sb.append("validate(buildable);\n"); sb.append("return buildable;\n"); return sb.toString(); }
private static Set<JavaType> findGenerifiables(Set<JavaClazz> interfaces) { if (interfaces.size() < 2) { return Collections.<JavaType>emptySet(); } //1st pass find all generics Set<JavaType> allGenerics = new LinkedHashSet<JavaType>(); for (JavaClazz clazz : interfaces) { popullateGenericTypes(clazz.getType(), allGenerics); } //2nd pass collect common generics Set<JavaType> common = new LinkedHashSet<JavaType>(allGenerics); for (JavaClazz clazz : interfaces) { Set<JavaType> ownGenerics = new LinkedHashSet<JavaType>(); popullateGenericTypes(clazz.getType(), ownGenerics); common.remove(clazz.getType()); common.retainAll(ownGenerics); } Set<JavaType> result = new LinkedHashSet<JavaType>(); for (JavaType type : common) { Boolean isGeneric = type.getAttributes().containsKey(IS_GENERIC) ? (Boolean) type.getAttributes().get(IS_GENERIC) : false; if (!isGeneric) { result.add(type); } } return result; }