use of com.squareup.javapoet.FieldSpec in project DeepLinkDispatch by airbnb.
the class DeepLinkProcessor method generateDeepLinkDelegate.
private void generateDeepLinkDelegate(String packageName, List<TypeElement> loaderClasses) throws IOException {
MethodSpec notifyListenerMethod = MethodSpec.methodBuilder("notifyListener").addModifiers(Modifier.PRIVATE, Modifier.STATIC).returns(void.class).addParameter(ANDROID_CONTEXT, "context").addParameter(boolean.class, "isError").addParameter(ClassName.get("android.net", "Uri"), "uri").addParameter(String.class, "errorMessage").addStatement("$T intent = new Intent()", ANDROID_INTENT).addStatement("intent.setAction($T.ACTION)", DeepLinkHandler.class).addStatement("intent.putExtra($T.EXTRA_URI, uri != null ? uri.toString() : $S)", DeepLinkHandler.class, "").addStatement("intent.putExtra($T.EXTRA_SUCCESSFUL, !isError)", DeepLinkHandler.class).beginControlFlow("if (isError)").addStatement("intent.putExtra($T.EXTRA_ERROR_MESSAGE, errorMessage)", DeepLinkHandler.class).endControlFlow().addStatement("$T.getInstance(context).sendBroadcast(intent)", ClassName.get("android.support.v4.content", "LocalBroadcastManager")).build();
ClassName deepLinkResult = ClassName.get(DLD_PACKAGE_NAME, "DeepLinkResult");
MethodSpec createResultAndNotifyMethod = MethodSpec.methodBuilder("createResultAndNotify").addModifiers(Modifier.PRIVATE, Modifier.STATIC).returns(deepLinkResult).addParameter(ANDROID_CONTEXT, "context").addParameter(TypeName.BOOLEAN, "successful", Modifier.FINAL).addParameter(ANDROID_URI, "uri", Modifier.FINAL).addParameter(ClassName.get(String.class), "error", Modifier.FINAL).addStatement("notifyListener(context, !successful, uri, error)").addStatement("return new $T(successful, uri != null ? uri.toString() : null, error)", deepLinkResult).build();
FieldSpec tag = FieldSpec.builder(String.class, "TAG", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("DeepLinkDelegate.class.getSimpleName()").build();
FieldSpec loaders = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(List.class), WildcardTypeName.subtypeOf(Parser.class)), "loaders", Modifier.PRIVATE, Modifier.FINAL).build();
CodeBlock.Builder loadersInitializer = CodeBlock.builder().add("this.loaders = $T.asList(\n", ClassName.get(Arrays.class)).indent();
int totalElements = loaderClasses.size();
for (int i = 0; i < totalElements; i++) {
loadersInitializer.add("$L$L", decapitalize(moduleNameToLoaderName(loaderClasses.get(i))), i < totalElements - 1 ? "," : "");
}
MethodSpec constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addParameters(FluentIterable.from(loaderClasses).transform(new Function<TypeElement, ParameterSpec>() {
@Override
public ParameterSpec apply(TypeElement typeElement) {
return ParameterSpec.builder(moduleElementToLoaderClassName(typeElement), decapitalize(moduleNameToLoaderName(typeElement))).build();
}
}).toList()).addCode(loadersInitializer.unindent().add(");\n").build()).build();
MethodSpec supportsUri = MethodSpec.methodBuilder("supportsUri").addModifiers(Modifier.PUBLIC).returns(TypeName.BOOLEAN).addParameter(String.class, "uriString").addStatement("return findEntry(uriString) != null").build();
MethodSpec findEntry = MethodSpec.methodBuilder("findEntry").addModifiers(Modifier.PRIVATE).returns(CLASS_DLD_ENTRY).addParameter(String.class, "uriString").beginControlFlow("for (Parser loader : loaders)").addStatement("$T entry = loader.parseUri(uriString)", CLASS_DLD_ENTRY).beginControlFlow("if (entry != null)").addStatement("return entry").endControlFlow().endControlFlow().addStatement("return null").build();
MethodSpec dispatchFromMethod = MethodSpec.methodBuilder("dispatchFrom").addModifiers(Modifier.PUBLIC).returns(deepLinkResult).addParameter(ANDROID_ACTIVITY, "activity").beginControlFlow("if (activity == null)").addStatement("throw new $T($S)", NullPointerException.class, "activity == null").endControlFlow().addStatement("return dispatchFrom(activity, activity.getIntent())").build();
MethodSpec dispatchFromMethodWithIntent = MethodSpec.methodBuilder("dispatchFrom").addModifiers(Modifier.PUBLIC).returns(deepLinkResult).addParameter(ANDROID_ACTIVITY, "activity").addParameter(ANDROID_INTENT, "sourceIntent").beginControlFlow("if (activity == null)").addStatement("throw new $T($S)", NullPointerException.class, "activity == null").endControlFlow().beginControlFlow("if (sourceIntent == null)").addStatement("throw new $T($S)", NullPointerException.class, "sourceIntent == null").endControlFlow().addStatement("$T uri = sourceIntent.getData()", ANDROID_URI).beginControlFlow("if (uri == null)").addStatement("return createResultAndNotify(activity, false, null, $S)", "No Uri in given activity's intent.").endControlFlow().addStatement("String uriString = uri.toString()").addStatement("$T entry = findEntry(uriString)", CLASS_DLD_ENTRY).beginControlFlow("if (entry != null)").addStatement("$T deepLinkUri = DeepLinkUri.parse(uriString)", CLASS_DLD_URI).addStatement("$T<String, String> parameterMap = entry.getParameters(uriString)", Map.class).beginControlFlow("for (String queryParameter : deepLinkUri.queryParameterNames())").beginControlFlow("for (String queryParameterValue : deepLinkUri.queryParameterValues(queryParameter))").beginControlFlow("if (parameterMap.containsKey(queryParameter))").addStatement("$T.w(TAG, \"Duplicate parameter name in path and query param: \" + queryParameter)", ClassName.get("android.util", "Log")).endControlFlow().addStatement("parameterMap.put(queryParameter, queryParameterValue)").endControlFlow().endControlFlow().addStatement("parameterMap.put($T.URI, uri.toString())", ClassName.get(DLD_PACKAGE_NAME, "DeepLink")).addStatement("$T parameters", ANDROID_BUNDLE).beginControlFlow("if (sourceIntent.getExtras() != null)").addStatement("parameters = new Bundle(sourceIntent.getExtras())").nextControlFlow("else").addStatement("parameters = new Bundle()").endControlFlow().beginControlFlow("for (Map.Entry<String, String> parameterEntry : parameterMap.entrySet())").addStatement("parameters.putString(parameterEntry.getKey(), parameterEntry.getValue())").endControlFlow().beginControlFlow("try").addStatement("Class<?> c = entry.getActivityClass()").addStatement("$T newIntent", ANDROID_INTENT).addStatement("$T taskStackBuilder = null", TASK_STACK_BUILDER).beginControlFlow("if (entry.getType() == DeepLinkEntry.Type.CLASS)").addStatement("newIntent = new Intent(activity, c)").nextControlFlow("else").addStatement("$T method", Method.class).beginControlFlow("try").addStatement("method = c.getMethod(entry.getMethod(), $T.class)", ANDROID_CONTEXT).beginControlFlow("if (method.getReturnType().equals($T.class))", TASK_STACK_BUILDER).addStatement("taskStackBuilder = (TaskStackBuilder) method.invoke(c, activity)").beginControlFlow("if (taskStackBuilder.getIntentCount() == 0)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod() + \" intents length == 0\" )").endControlFlow().addStatement("newIntent = taskStackBuilder." + "editIntentAt(taskStackBuilder.getIntentCount()-1)").nextControlFlow("else").addStatement("newIntent = (Intent) method.invoke(c, activity)").endControlFlow().nextControlFlow("catch ($T exception)", NoSuchMethodException.class).addStatement("method = c.getMethod(entry.getMethod(), $T.class, $T.class)", ANDROID_CONTEXT, ANDROID_BUNDLE).beginControlFlow("if (method.getReturnType().equals($T.class))", TASK_STACK_BUILDER).addStatement("taskStackBuilder = " + "(TaskStackBuilder) method.invoke(c, activity, parameters)").beginControlFlow("if (taskStackBuilder.getIntentCount() == 0)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod() + \" intents length == 0\" )").endControlFlow().addStatement("newIntent = taskStackBuilder." + "editIntentAt(taskStackBuilder.getIntentCount()-1)").nextControlFlow("else").addStatement("newIntent = (Intent) method.invoke(c, activity, parameters)").endControlFlow().endControlFlow().endControlFlow().beginControlFlow("if (newIntent.getAction() == null)").addStatement("newIntent.setAction(sourceIntent.getAction())").endControlFlow().beginControlFlow("if (newIntent.getData() == null)").addStatement("newIntent.setData(sourceIntent.getData())").endControlFlow().addStatement("newIntent.putExtras(parameters)").addStatement("newIntent.putExtra(DeepLink.IS_DEEP_LINK, true)").addStatement("newIntent.putExtra(DeepLink.REFERRER_URI, uri)").beginControlFlow("if (activity.getCallingActivity() != null)").addStatement("newIntent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)").endControlFlow().beginControlFlow("if (taskStackBuilder != null)").addStatement("taskStackBuilder.startActivities()").nextControlFlow("else").addStatement("activity.startActivity(newIntent)").endControlFlow().addStatement("return createResultAndNotify(activity, true, uri, null)").nextControlFlow("catch (NoSuchMethodException exception)").addStatement("return createResultAndNotify(activity, false, uri, \"Deep link to " + "non-existent method: \" + entry.getMethod())").nextControlFlow("catch (IllegalAccessException exception)").addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod())").nextControlFlow("catch ($T exception)", InvocationTargetException.class).addStatement("return createResultAndNotify(activity, false, uri, \"Could not deep " + "link to method: \" + entry.getMethod())").endControlFlow().nextControlFlow("else").addStatement("return createResultAndNotify(activity, false, uri, " + "\"No registered entity to handle deep link: \" + uri.toString())").endControlFlow().build();
TypeSpec deepLinkDelegate = TypeSpec.classBuilder("DeepLinkDelegate").addModifiers(Modifier.PUBLIC, Modifier.FINAL).addField(tag).addField(loaders).addMethod(constructor).addMethod(findEntry).addMethod(dispatchFromMethod).addMethod(dispatchFromMethodWithIntent).addMethod(createResultAndNotifyMethod).addMethod(notifyListenerMethod).addMethod(supportsUri).build();
JavaFile.builder(packageName, deepLinkDelegate).build().writeTo(filer);
}
use of com.squareup.javapoet.FieldSpec in project wire by square.
the class JavaGenerator method generateEnum.
/** @deprecated Use {@link #generateType(Type)} */
@Deprecated
public TypeSpec generateEnum(EnumType type) {
ClassName javaType = (ClassName) typeName(type.type());
TypeSpec.Builder builder = TypeSpec.enumBuilder(javaType.simpleName()).addModifiers(PUBLIC).addSuperinterface(WireEnum.class);
if (!type.documentation().isEmpty()) {
builder.addJavadoc("$L\n", sanitizeJavadoc(type.documentation()));
}
// Output Private tag field
builder.addField(TypeName.INT, "value", PRIVATE, FINAL);
MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder();
constructorBuilder.addStatement("this.value = value");
constructorBuilder.addParameter(TypeName.INT, "value");
// Enum constant options, each of which requires a constructor parameter and a field.
Set<ProtoMember> allOptionFieldsBuilder = new LinkedHashSet<>();
for (EnumConstant constant : type.constants()) {
for (ProtoMember protoMember : constant.options().map().keySet()) {
Field optionField = schema.getField(protoMember);
if (allOptionFieldsBuilder.add(protoMember)) {
TypeName optionJavaType = typeName(optionField.type());
builder.addField(optionJavaType, optionField.name(), PUBLIC, FINAL);
constructorBuilder.addParameter(optionJavaType, optionField.name());
constructorBuilder.addStatement("this.$L = $L", optionField.name(), optionField.name());
}
}
}
ImmutableList<ProtoMember> allOptionMembers = ImmutableList.copyOf(allOptionFieldsBuilder);
String enumArgsFormat = "$L" + Strings.repeat(", $L", allOptionMembers.size());
builder.addMethod(constructorBuilder.build());
MethodSpec.Builder fromValueBuilder = MethodSpec.methodBuilder("fromValue").addJavadoc("Return the constant for {@code value} or null.\n").addModifiers(PUBLIC, STATIC).returns(javaType).addParameter(int.class, "value").beginControlFlow("switch (value)");
Set<Integer> seenTags = new LinkedHashSet<>();
for (EnumConstant constant : type.constants()) {
Object[] enumArgs = new Object[allOptionMembers.size() + 1];
enumArgs[0] = constant.tag();
for (int i = 0; i < allOptionMembers.size(); i++) {
ProtoMember protoMember = allOptionMembers.get(i);
Field field = schema.getField(protoMember);
Object value = constant.options().map().get(protoMember);
enumArgs[i + 1] = value != null ? fieldInitializer(field.type(), value) : null;
}
TypeSpec.Builder constantBuilder = TypeSpec.anonymousClassBuilder(enumArgsFormat, enumArgs);
if (!constant.documentation().isEmpty()) {
constantBuilder.addJavadoc("$L\n", sanitizeJavadoc(constant.documentation()));
}
if ("true".equals(constant.options().get(ENUM_DEPRECATED))) {
constantBuilder.addAnnotation(Deprecated.class);
}
builder.addEnumConstant(constant.name(), constantBuilder.build());
// Ensure constant case tags are unique, which might not be the case if allow_alias is true.
if (seenTags.add(constant.tag())) {
fromValueBuilder.addStatement("case $L: return $L", constant.tag(), constant.name());
}
}
builder.addMethod(fromValueBuilder.addStatement("default: return null").endControlFlow().build());
// ADAPTER
FieldSpec.Builder adapterBuilder = FieldSpec.builder(adapterOf(javaType), "ADAPTER").addModifiers(PUBLIC, STATIC, FINAL);
ClassName adapterJavaType = javaType.nestedClass("ProtoAdapter_" + javaType.simpleName());
if (!emitCompact) {
adapterBuilder.initializer("new $T()", adapterJavaType);
} else {
adapterBuilder.initializer("$T.newEnumAdapter($T.class)", ProtoAdapter.class, javaType);
}
builder.addField(adapterBuilder.build());
// Enum type options.
FieldSpec options = optionsField(ENUM_OPTIONS, "ENUM_OPTIONS", type.options());
if (options != null) {
builder.addField(options);
}
// Public Getter
builder.addMethod(MethodSpec.methodBuilder("getValue").addAnnotation(Override.class).addModifiers(PUBLIC).returns(TypeName.INT).addStatement("return value").build());
if (!emitCompact) {
// Adds the ProtoAdapter implementation at the bottom.
builder.addType(enumAdapter(javaType, adapterJavaType));
}
return builder.build();
}
use of com.squareup.javapoet.FieldSpec in project wire by square.
the class JavaGenerator method generateMessage.
/** @deprecated Use {@link #generateType(Type)} */
@Deprecated
public TypeSpec generateMessage(MessageType type) {
NameAllocator nameAllocator = nameAllocators.getUnchecked(type);
ClassName javaType = (ClassName) typeName(type.type());
ClassName builderJavaType = javaType.nestedClass("Builder");
TypeSpec.Builder builder = TypeSpec.classBuilder(javaType.simpleName());
builder.addModifiers(PUBLIC, FINAL);
if (javaType.enclosingClassName() != null) {
builder.addModifiers(STATIC);
}
if (!type.documentation().isEmpty()) {
builder.addJavadoc("$L\n", sanitizeJavadoc(type.documentation()));
}
ClassName messageType = emitAndroid ? ANDROID_MESSAGE : MESSAGE;
builder.superclass(messageOf(messageType, javaType, builderJavaType));
String adapterName = nameAllocator.get("ADAPTER");
String protoAdapterName = "ProtoAdapter_" + javaType.simpleName();
String protoAdapterClassName = nameAllocator.newName(protoAdapterName);
ClassName adapterJavaType = javaType.nestedClass(protoAdapterClassName);
builder.addField(messageAdapterField(adapterName, javaType, adapterJavaType));
if (emitAndroid) {
TypeName creatorType = creatorOf(javaType);
String creatorName = nameAllocator.get("CREATOR");
builder.addField(FieldSpec.builder(creatorType, creatorName, PUBLIC, STATIC, FINAL).initializer("$T.newCreator($L)", ANDROID_MESSAGE, adapterName).build());
}
builder.addField(FieldSpec.builder(TypeName.LONG, nameAllocator.get("serialVersionUID")).addModifiers(PRIVATE, STATIC, FINAL).initializer("$LL", 0L).build());
FieldSpec messageOptions = optionsField(MESSAGE_OPTIONS, nameAllocator.get("MESSAGE_OPTIONS"), type.options());
if (messageOptions != null) {
builder.addField(messageOptions);
}
for (Field field : type.fieldsAndOneOfFields()) {
String fieldName = nameAllocator.get(field);
String optionsFieldName = "FIELD_OPTIONS_" + fieldName.toUpperCase(Locale.US);
FieldSpec fieldOptions = optionsField(FIELD_OPTIONS, optionsFieldName, field.options());
if (fieldOptions != null) {
builder.addField(fieldOptions);
}
}
for (Field field : type.fieldsAndOneOfFields()) {
TypeName fieldJavaType = fieldType(field);
if ((field.type().isScalar() || isEnum(field.type())) && !field.isRepeated() && !field.isPacked()) {
builder.addField(defaultField(nameAllocator, field, fieldJavaType));
}
String fieldName = nameAllocator.get(field);
FieldSpec.Builder fieldBuilder = FieldSpec.builder(fieldJavaType, fieldName, PUBLIC, FINAL);
fieldBuilder.addAnnotation(wireFieldAnnotation(field));
if (!field.documentation().isEmpty()) {
fieldBuilder.addJavadoc("$L\n", sanitizeJavadoc(field.documentation()));
}
if (field.isExtension()) {
fieldBuilder.addJavadoc("Extension source: $L\n", field.location().withPathOnly());
}
if (field.isDeprecated()) {
fieldBuilder.addAnnotation(Deprecated.class);
}
if (emitAndroid && field.isOptional()) {
fieldBuilder.addAnnotation(NULLABLE);
}
builder.addField(fieldBuilder.build());
}
builder.addMethod(messageFieldsConstructor(nameAllocator, type));
builder.addMethod(messageFieldsAndUnknownFieldsConstructor(nameAllocator, type));
builder.addMethod(newBuilder(nameAllocator, type));
builder.addMethod(messageEquals(nameAllocator, type));
builder.addMethod(messageHashCode(nameAllocator, type));
if (!emitCompact) {
builder.addMethod(messageToString(nameAllocator, type));
}
builder.addType(builder(nameAllocator, type, javaType, builderJavaType));
for (Type nestedType : type.nestedTypes()) {
builder.addType(generateType(nestedType));
}
if (!emitCompact) {
// Add the ProtoAdapter implementation at the very bottom since it's ugly serialization code.
builder.addType(messageAdapter(nameAllocator, type, javaType, adapterJavaType, builderJavaType));
}
return builder.build();
}
use of com.squareup.javapoet.FieldSpec in project potato by eyeem.
the class CodeWriter method process.
private void process() throws ClassNotFoundException, IOException {
// Build fields
ArrayList<FieldSpec> fields = new ArrayList<>();
FieldSpec field;
//FieldSpec.builder(String.class, "instance", Modifier.PRIVATE, Modifier.STATIC);
field = FieldSpec.builder(generatedClass, "instance").addModifiers(Modifier.PRIVATE, Modifier.STATIC).build();
fields.add(field);
// Build methods
ArrayList<MethodSpec> methods = new ArrayList<>();
MethodSpec method;
method = MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).addParameter(context, "context").addStatement("super(context)").build();
methods.add(method);
method = MethodSpec.methodBuilder("id").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).addParameter(dataClass, "object").returns(String.class).addStatement("return object." + id).build();
methods.add(method);
method = MethodSpec.methodBuilder("classname").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).returns(Class.class).addStatement("return $T.class", dataClass).build();
methods.add(method);
method = MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC, Modifier.STATIC).addParameter(context, "context").returns(generatedClass).addStatement("if(instance == null) initialise(context)").addStatement("return instance").build();
methods.add(method);
method = MethodSpec.methodBuilder("initialise").addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.SYNCHRONIZED).addParameter(context, "context").beginControlFlow("if(instance == null)").addStatement("instance = new $T(context)", generatedClass).addStatement("instance.init()").endControlFlow().build();
methods.add(method);
// build class
TypeSpec.Builder builder = TypeSpec.classBuilder(generatedClassName).addModifiers(Modifier.PUBLIC).superclass(ParameterizedTypeName.get(ClassName.get("com.eyeem.storage", "Storage"), dataClass));
for (FieldSpec fieldSpec : fields) builder.addField(fieldSpec);
for (MethodSpec methodSpec : methods) builder.addMethod(methodSpec);
TypeSpec typeSpec = builder.build();
JavaFile javaFile = JavaFile.builder(packageName, typeSpec).build();
Writer writer = filer.createSourceFile(packageName + "." + generatedClassName).openWriter();
javaFile.writeTo(writer);
writer.close();
}
use of com.squareup.javapoet.FieldSpec in project requery by requery.
the class EntityMetaGenerator method generateAttribute.
private FieldSpec generateAttribute(AttributeDescriptor attribute, AttributeDescriptor parent, TypeName targetName, String fieldName, TypeMirror mirror, boolean expression) {
TypeMirror typeMirror = mirror;
TypeName typeName;
if (attribute.isIterable()) {
typeMirror = tryFirstTypeArgument(typeMirror);
typeName = parameterizedCollectionName(attribute.typeMirror());
} else if (attribute.isOptional()) {
typeMirror = tryFirstTypeArgument(typeMirror);
typeName = TypeName.get(typeMirror);
} else {
typeName = nameResolver.generatedTypeNameOf(typeMirror).orElse(null);
}
if (typeName == null) {
typeName = boxedTypeName(typeMirror);
}
ParameterizedTypeName type;
ClassName attributeType = null;
boolean useKotlinDelegate = false;
if (expression) {
type = parameterizedTypeName(QueryExpression.class, typeName);
} else {
// if it's an association don't make it available as a query attribute
boolean isQueryable = attribute.cardinality() == null || attribute.isForeignKey();
Class<?> attributeClass = isQueryable ? QueryAttribute.class : Attribute.class;
attributeType = ClassName.get(attributeClass);
if (isQueryable) {
TypeElement delegateType = elements.getTypeElement(KOTLIN_ATTRIBUTE_DELEGATE);
if (delegateType != null) {
attributeType = ClassName.get(delegateType);
useKotlinDelegate = true;
}
}
type = ParameterizedTypeName.get(attributeType, targetName, typeName);
}
CodeBlock.Builder builder = CodeBlock.builder();
String attributeName = attribute.name();
if (parent != null && parent.isEmbedded()) {
attributeName = embeddedAttributeName(parent, attribute);
}
if (attribute.isIterable()) {
typeMirror = tryFirstTypeArgument(typeMirror);
TypeName name = nameResolver.tryGeneratedTypeName(typeMirror);
TypeElement collection = (TypeElement) types.asElement(attribute.typeMirror());
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName, name);
builder.add("\nnew $T($S, $T.class, $T.class)\n", builderName, attributeName, ClassName.get(collection), name);
} else if (attribute.isMap() && attribute.cardinality() != null) {
List<TypeMirror> parameters = Mirrors.listGenericTypeArguments(typeMirror);
// key type
TypeName keyName = TypeName.get(parameters.get(0));
// value type
typeMirror = parameters.get(1);
TypeName valueName = nameResolver.tryGeneratedTypeName(typeMirror);
TypeElement valueElement = (TypeElement) types.asElement(attribute.typeMirror());
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName, keyName, valueName);
builder.add("\nnew $T($S, $T.class, $T.class, $T.class)\n", builderName, attributeName, ClassName.get(valueElement), keyName, valueName);
} else {
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName);
TypeName classType = typeName;
if (typeMirror.getKind().isPrimitive()) {
// if primitive just use the primitive class not the boxed version
classType = TypeName.get(typeMirror);
}
String statement;
if (Mirrors.listGenericTypeArguments(typeMirror).size() > 0) {
// use the erased type and cast to class
classType = TypeName.get(types.erasure(typeMirror));
statement = "\nnew $T($S, (Class)$T.class)\n";
} else {
statement = "\nnew $T($S, $T.class)\n";
}
builder.add(statement, builderName, attributeName, classType);
}
if (!expression) {
generateProperties(attribute, parent, typeMirror, targetName, typeName, builder);
}
// attribute builder properties
if (attribute.isKey()) {
builder.add(".setKey(true)\n");
}
builder.add(".setGenerated($L)\n", attribute.isGenerated());
builder.add(".setLazy($L)\n", attribute.isLazy());
builder.add(".setNullable($L)\n", attribute.isNullable());
builder.add(".setUnique($L)\n", attribute.isUnique());
if (!Names.isEmpty(attribute.defaultValue())) {
builder.add(".setDefaultValue($S)\n", attribute.defaultValue());
}
if (!Names.isEmpty(attribute.collate())) {
builder.add(".setCollate($S)\n", attribute.collate());
}
if (attribute.columnLength() != null) {
builder.add(".setLength($L)\n", attribute.columnLength());
}
if (!Names.isEmpty(attribute.definition())) {
builder.add(".setDefinition($S)\n", attribute.definition());
}
if (attribute.isVersion()) {
builder.add(".setVersion($L)\n", attribute.isVersion());
}
if (attribute.converterName() != null) {
builder.add(".setConverter(new $L())\n", attribute.converterName());
}
if (attribute.isForeignKey()) {
builder.add(".setForeignKey($L)\n", attribute.isForeignKey());
Optional<EntityDescriptor> referencedType = graph.referencingEntity(attribute);
referencedType.ifPresent(referenced -> {
builder.add(".setReferencedClass($T.class)\n", referenced.isImmutable() ? TypeName.get(referenced.element().asType()) : nameResolver.typeNameOf(referenced));
graph.referencingAttribute(attribute, referenced).ifPresent(referencedAttribute -> {
String name = upperCaseUnderscoreRemovePrefixes(referencedAttribute.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), name).build());
builder.add(".setReferencedAttribute($L)\n", provider);
});
});
}
if (attribute.isIndexed()) {
builder.add(".setIndexed($L)\n", attribute.isIndexed());
if (!attribute.indexNames().isEmpty()) {
StringJoiner joiner = new StringJoiner(",");
attribute.indexNames().forEach(name -> joiner.add("$S"));
builder.add(".setIndexNames(" + joiner + ")\n", attribute.indexNames().toArray());
}
}
if (attribute.deleteAction() != null) {
builder.add(".setDeleteAction($T.$L)\n", ClassName.get(ReferentialAction.class), attribute.deleteAction());
}
if (attribute.updateAction() != null) {
builder.add(".setUpdateAction($T.$L)\n", ClassName.get(ReferentialAction.class), attribute.updateAction());
}
if (!attribute.cascadeActions().isEmpty()) {
StringJoiner joiner = new StringJoiner(",");
attribute.cascadeActions().forEach(action -> joiner.add("$T.$L"));
int index = 0;
ClassName cascadeClass = ClassName.get(CascadeAction.class);
Object[] args = new Object[attribute.cascadeActions().size() * 2];
for (CascadeAction action : attribute.cascadeActions()) {
args[index++] = cascadeClass;
args[index++] = action;
}
builder.add(".setCascadeAction(" + joiner + ")\n", args);
}
if (attribute.cardinality() != null) {
if (!expression) {
builder.add(".setCardinality($T.$L)\n", ClassName.get(Cardinality.class), attribute.cardinality());
}
graph.referencingEntity(attribute).ifPresent(referenced -> {
Set<AttributeDescriptor> mappings = graph.mappedAttributes(entity, attribute, referenced);
if (attribute.cardinality() == Cardinality.MANY_TO_MANY) {
generateJunctionType(attribute, referenced, mappings).ifPresent(name -> builder.add(".setReferencedClass($T.class)\n", name));
}
if (mappings.size() == 1) {
AttributeDescriptor mapped = mappings.iterator().next();
String staticMemberName = upperCaseUnderscoreRemovePrefixes(mapped.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), staticMemberName).build());
builder.add(".setMappedAttribute($L)\n", provider);
}
if (attribute.orderBy() != null) {
referenced.attributes().values().stream().filter(entry -> entry.name().equals(attribute.orderBy())).findFirst().ifPresent(orderBy -> {
String staticMemberName = upperCaseUnderscoreRemovePrefixes(orderBy.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), staticMemberName).build());
builder.add(".setOrderByAttribute($L)\n", provider);
builder.add(".setOrderByDirection($T.$L)\n", ClassName.get(Order.class), attribute.orderByDirection());
});
}
});
}
builder.add(".build()");
FieldSpec.Builder field = FieldSpec.builder(type, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
if (useKotlinDelegate) {
return field.initializer("new $T($L)", attributeType, builder.build()).build();
} else {
return field.initializer("$L", builder.build()).build();
}
}
Aggregations