Skip to content

Commit

Permalink
Micronaut PUT/POST Data Endpoint Method generation added.
Browse files Browse the repository at this point in the history
  • Loading branch information
dbalek committed Feb 15, 2024
1 parent d30134f commit 1518595
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
Expand All @@ -36,7 +35,6 @@
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.swing.text.Document;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
import org.netbeans.api.java.source.CompilationInfo;
Expand Down Expand Up @@ -67,8 +65,9 @@ public class MicronautDataCompletionCollector implements CompletionCollector {
public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
new MicronautDataCompletionTask().query(doc, offset, new MicronautDataCompletionTask.ItemFactory<Completion>() {
@Override
public Completion createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String id, int offset) {
String methodName = Utils.getEndpointMethodName(delegateMethod.getSimpleName().toString(), id);
public Completion createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String controllerId, String id, int offset) {
String delegateMethodName = delegateMethod.getSimpleName().toString();
String methodName = Utils.getControllerDataEndpointMethodName(delegateMethodName, id);
TypeMirror delegateRepositoryType = delegateRepository.asType();
if (delegateRepositoryType.getKind() == TypeKind.DECLARED) {
ExecutableType type = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) delegateRepositoryType, delegateMethod);
Expand All @@ -85,7 +84,7 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
break;
}
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, delegateMethod.isVarArgs() && !tIt.hasNext()).toString();
String paramTypeName = Utils.getTypeName(info, tm, false, delegateMethod.isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
labelDetail.append(paramTypeName).append(' ').append(paramName);
sortParams.append(paramTypeName);
Expand All @@ -96,21 +95,14 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
}
sortParams.append(')');
labelDetail.append(')');
TypeMirror returnType = type.getReturnType();
if ("findAll".contentEquals(delegateMethod.getSimpleName()) && !delegateMethod.getParameters().isEmpty() && returnType.getKind() == TypeKind.DECLARED) {
TypeElement te = (TypeElement) ((DeclaredType) returnType).asElement();
Optional<ExecutableElement> getContentMethod = ElementFilter.methodsIn(te.getEnclosedElements()).stream().filter(m -> "getContent".contentEquals(m.getSimpleName()) && m.getParameters().isEmpty()).findAny();
if (getContentMethod.isPresent()) {
returnType = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) returnType, getContentMethod.get());
}
}
TypeMirror returnType = Utils.getControllerDataEndpointReturnType(info, delegateMethodName, type);
FileObject fo = info.getFileObject();
ElementHandle<VariableElement> repositoryHandle = ElementHandle.create(delegateRepository);
ElementHandle<ExecutableElement> methodHandle = ElementHandle.create(delegateMethod);
return CompletionCollector.newBuilder(methodName)
.kind(Completion.Kind.Method)
.labelDetail(String.format("%s - generate", labelDetail.toString()))
.labelDescription(MicronautDataCompletionTask.getTypeName(info, returnType, false, false).toString())
.labelDescription(Utils.getTypeName(info, returnType, false, false).toString())
.sortText(String.format("%04d%s#%02d%s", 1500, methodName, cnt, sortParams.toString()))
.insertTextFormat(Completion.TextFormat.PlainText)
.textEdit(new TextEdit(offset, offset, ""))
Expand All @@ -125,7 +117,7 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
if (repository != null && method != null) {
TypeMirror repositoryType = repository.asType();
if (repositoryType.getKind() == TypeKind.DECLARED) {
MethodTree mt = Utils.createControllerDataEndpointMethod(wc, (DeclaredType) repositoryType, repository.getSimpleName().toString(), method, id);
MethodTree mt = Utils.createControllerDataEndpointMethod(wc, (DeclaredType) repositoryType, repository.getSimpleName().toString(), method, controllerId, id);
wc.rewrite(clazz, GeneratorUtilities.get(wc).insertClassMember(clazz, mt, offset));
}
}
Expand Down Expand Up @@ -218,7 +210,7 @@ public Completion createJavaElementItem(CompilationInfo info, Element element, i
break;
}
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, ((ExecutableElement)element).isVarArgs() && !tIt.hasNext()).toString();
String paramTypeName = Utils.getTypeName(info, tm, false, ((ExecutableElement)element).isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
labelDetail.append(paramTypeName).append(' ').append(paramName);
sortParams.append(paramTypeName);
Expand All @@ -236,7 +228,7 @@ public Completion createJavaElementItem(CompilationInfo info, Element element, i
return CompletionCollector.newBuilder(simpleName)
.kind(Completion.Kind.Method)
.labelDetail(labelDetail.toString())
.labelDescription(MicronautDataCompletionTask.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString())
.labelDescription(Utils.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString())
.sortText(String.format("%04d%s#%02d%s", 100, simpleName, cnt, sortParams.toString()))
.insertText(insertText.toString())
.insertTextFormat(asTemplate ? Completion.TextFormat.Snippet : Completion.TextFormat.PlainText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
import com.sun.source.util.TreePath;
import java.awt.Color;
import java.io.CharConversionException;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import javax.lang.model.element.Element;
Expand All @@ -39,7 +39,6 @@
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.swing.Action;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
Expand All @@ -58,6 +57,7 @@
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.api.Source;
import org.netbeans.modules.parsing.api.UserTask;
import org.netbeans.modules.parsing.spi.ParseException;
import org.netbeans.spi.editor.completion.CompletionDocumentation;
import org.netbeans.spi.editor.completion.CompletionItem;
import org.netbeans.spi.editor.completion.CompletionProvider;
Expand Down Expand Up @@ -119,8 +119,9 @@ protected void query(CompletionResultSet resultSet, Document doc, int caretOffse
MicronautDataCompletionTask task = new MicronautDataCompletionTask();
resultSet.addAllItems(task.query(doc, caretOffset, new MicronautDataCompletionTask.ItemFactory<CompletionItem>() {
@Override
public CompletionItem createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String id, int offset) {
String methodName = Utils.getEndpointMethodName(delegateMethod.getSimpleName().toString(), id);
public CompletionItem createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String controllerId, String id, int offset) {
String delegateMethodName = delegateMethod.getSimpleName().toString();
String methodName = Utils.getControllerDataEndpointMethodName(delegateMethodName, id);
TypeMirror delegateRepositoryType = delegateRepository.asType();
if (delegateRepositoryType.getKind() == TypeKind.DECLARED) {
ExecutableType type = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) delegateRepositoryType, delegateMethod);
Expand All @@ -137,7 +138,7 @@ public CompletionItem createControllerMethodItem(CompilationInfo info, VariableE
break;
}
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, delegateMethod.isVarArgs() && !tIt.hasNext()).toString();
String paramTypeName = Utils.getTypeName(info, tm, false, delegateMethod.isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
label.append(escape(paramTypeName)).append(' ').append(PARAMETER_NAME_COLOR).append(paramName).append(COLOR_END);
sortParams.append(paramTypeName);
Expand All @@ -148,21 +149,14 @@ public CompletionItem createControllerMethodItem(CompilationInfo info, VariableE
}
label.append(')');
sortParams.append(')');
TypeMirror returnType = type.getReturnType();
if ("findAll".contentEquals(delegateMethod.getSimpleName()) && !delegateMethod.getParameters().isEmpty() && returnType.getKind() == TypeKind.DECLARED) {
TypeElement te = (TypeElement) ((DeclaredType) returnType).asElement();
Optional<ExecutableElement> getContentMethod = ElementFilter.methodsIn(te.getEnclosedElements()).stream().filter(m -> "getContent".contentEquals(m.getSimpleName()) && m.getParameters().isEmpty()).findAny();
if (getContentMethod.isPresent()) {
returnType = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) returnType, getContentMethod.get());
}
}
TypeMirror returnType = Utils.getControllerDataEndpointReturnType(info, delegateMethodName, type);
ElementHandle<VariableElement> repositoryHandle = ElementHandle.create(delegateRepository);
ElementHandle<ExecutableElement> methodHandle = ElementHandle.create(delegateMethod);
return CompletionUtilities.newCompletionItemBuilder(methodName)
.startOffset(offset)
.iconResource(METHOD_PUBLIC)
.leftHtmlText(label.toString())
.rightHtmlText(MicronautDataCompletionTask.getTypeName(info, returnType, false, false).toString())
.rightHtmlText(Utils.getTypeName(info, returnType, false, false).toString())
.sortPriority(100)
.sortText(String.format("%s#%02d%s", methodName, cnt, sortParams.toString()))
.onSelect(ctx -> {
Expand All @@ -187,15 +181,15 @@ public void run(ResultIterator resultIterator) throws Exception {
if (repository != null && method != null) {
TypeMirror repositoryType = repository.asType();
if (repositoryType.getKind() == TypeKind.DECLARED) {
MethodTree mt = Utils.createControllerDataEndpointMethod(copy, (DeclaredType) repositoryType, repository.getSimpleName().toString(), method, id);
MethodTree mt = Utils.createControllerDataEndpointMethod(copy, (DeclaredType) repositoryType, repository.getSimpleName().toString(), method, controllerId, id);
copy.rewrite(clazz, GeneratorUtilities.get(copy).insertClassMember(clazz, mt, offset));
}
}
}
}
});
mr.commit();
} catch (Exception ex) {
} catch (IOException | ParseException ex) {
Exceptions.printStackTrace(ex);
}
}).build();
Expand Down Expand Up @@ -341,7 +335,7 @@ public CompletionItem createJavaElementItem(CompilationInfo info, Element elemen
break;
}
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, ((ExecutableElement)element).isVarArgs() && !tIt.hasNext()).toString();
String paramTypeName = Utils.getTypeName(info, tm, false, ((ExecutableElement)element).isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
label.append(escape(paramTypeName)).append(' ').append(PARAMETER_NAME_COLOR).append(paramName).append(COLOR_END);
sortParams.append(paramTypeName);
Expand All @@ -360,7 +354,7 @@ public CompletionItem createJavaElementItem(CompilationInfo info, Element elemen
.startOffset(offset)
.iconResource(element.getModifiers().contains(Modifier.STATIC) ? METHOD_ST_PUBLIC : METHOD_PUBLIC)
.leftHtmlText(label.toString())
.rightHtmlText(MicronautDataCompletionTask.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString())
.rightHtmlText(Utils.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString())
.sortPriority(100)
.sortText(String.format("%s#%02d%s", simpleName, cnt, sortParams.toString()))
.insertText(insertText.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
Expand Down Expand Up @@ -100,7 +98,7 @@ public class MicronautDataCompletionTask {
private int anchorOffset;

public static interface ItemFactory<T> extends MicronautExpressionLanguageCompletion.ItemFactory<T> {
T createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String id, int offset);
T createControllerMethodItem(CompilationInfo info, VariableElement delegateRepository, ExecutableElement delegateMethod, String controllerId, String id, int offset);
T createFinderMethodItem(String name, String returnType, int offset);
T createFinderMethodNameItem(String prefix, String name, int offset);
T createSQLItem(CompletionItem item);
Expand Down Expand Up @@ -248,8 +246,8 @@ private <T> List<T> resolveControllerMethods(CompilationController cc, TreePath
if (controllerAnn != null) {
List<VariableElement> repositories = Utils.getRepositoriesFor(cc, te);
if (!repositories.isEmpty()) {
Utils.collectMissingDataEndpoints(cc, te, prefix, (repository, delegateMethod, id) -> {
T item = factory.createControllerMethodItem(cc, repository, delegateMethod, id, anchorOffset);
Utils.collectMissingDataEndpoints(cc, te, prefix, (repository, delegateMethod, controllerId, id) -> {
T item = factory.createControllerMethodItem(cc, repository, delegateMethod, controllerId, id, anchorOffset);
if (item != null) {
items.add(item);
}
Expand Down Expand Up @@ -393,17 +391,6 @@ private static TokenSequence<JavaTokenId> previousNonWhitespaceToken(TokenSequen
return null;
}

static CharSequence getTypeName(CompilationInfo info, TypeMirror type, boolean fqn, boolean varArg) {
Set<TypeUtilities.TypeNameOptions> options = EnumSet.noneOf(TypeUtilities.TypeNameOptions.class);
if (fqn) {
options.add(TypeUtilities.TypeNameOptions.PRINT_FQN);
}
if (varArg) {
options.add(TypeUtilities.TypeNameOptions.PRINT_AS_VARARG);
}
return info.getTypeUtilities().getTypeName(type, options.toArray(new TypeUtilities.TypeNameOptions[0]));
}

@FunctionalInterface
private static interface Consumer {
void accept(String namePrefix, String name, String type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public <T> Result<T> query(int offset, ItemFactory<T> factory) {
}
String propertyName = element.getKind() == ElementKind.METHOD ? ExpressionTree.getPropertyName((ExecutableElement) element) : null;
if (Utils.startsWith(propertyName, prefix) && info.getTrees().isAccessible(ctx.getScope(), element, (DeclaredType) enclType)) {
String returnType = MicronautDataCompletionTask.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString();
String returnType = Utils.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString();
items.add(factory.createBeanPropertyItem(propertyName, returnType, anchorOffset));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;NotifyDescriptor.QuickPick.Item&gt;"/>
</AuxValues>
</Component>
</SubComponents>
Expand Down
Loading

0 comments on commit 1518595

Please sign in to comment.