Skip to content

Commit

Permalink
Merge pull request #7068 from dbalek/dbalek/micronaut-put-post-data-e…
Browse files Browse the repository at this point in the history
…ndpoints

Micronaut PUT/POST Data Endpoint Method generation added.
  • Loading branch information
dbalek authored Feb 16, 2024
2 parents 79b0ff6 + 1518595 commit a52aa9a
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 a52aa9a

Please sign in to comment.