| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.generator.swagger; |
| |
| import java.util.ArrayDeque; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Deque; |
| import java.util.List; |
| import java.util.StringJoiner; |
| import java.util.stream.Collectors; |
| |
| import com.squareup.javapoet.MethodSpec; |
| |
| import static org.apache.commons.lang3.ClassUtils.isPrimitiveOrWrapper; |
| |
| class MethodBodySourceCodeEmitter implements CodeEmitter<MethodSpec> { |
| |
| private final MethodSpec.Builder builder; |
| |
| private boolean first = true; |
| |
| private final Deque<Integer> indentIntentStack = new ArrayDeque<>(); |
| |
| private final Deque<Integer> indentStack = new ArrayDeque<>(); |
| |
| MethodBodySourceCodeEmitter(final MethodSpec.Builder builder) { |
| this.builder = builder; |
| indentStack.push(0); |
| } |
| |
| @Override |
| public CodeEmitter<MethodSpec> emit(final String method, final Object... args) { |
| final boolean hasArgs = args != null && args.length > 0; |
| |
| final int indent = indentLevelOf(method); |
| |
| if (!first) { |
| builder.addCode("\n"); |
| } |
| |
| builder.addCode(String.join("", Collections.nCopies(indentStack.peek(), "$<"))); |
| builder.addCode(String.join("", Collections.nCopies(indent, "$>"))); |
| |
| if (!first) { |
| builder.addCode("."); |
| } |
| |
| indentStack.push(indent); |
| |
| if (hasArgs) { |
| builder.addCode("$L(" + invocationLiteralsFor(args) + ")", extend(method, argumentsFor(args))); |
| } else { |
| builder.addCode("$L()", method); |
| } |
| |
| first = false; |
| |
| return this; |
| } |
| |
| @Override |
| public MethodSpec result() { |
| builder.addCode(String.join("", Collections.nCopies(indentStack.peek(), "$<"))); |
| builder.addCode(";\n"); |
| return builder.build(); |
| } |
| |
| Object[] argumentsFor(final Object[] args) { |
| final List<Object> arguments = new ArrayList<>(args.length); |
| |
| for (final Object arg : args) { |
| if (isPrimitiveOrWrapper(arg.getClass())) { |
| arguments.add(arg); |
| } else if (arg instanceof String) { |
| arguments.add(arg); |
| } else if (arg instanceof Enum) { |
| arguments.add(arg.getClass()); |
| arguments.add(arg); |
| } else if (arg instanceof String[]) { |
| arguments.add(Arrays.stream((String[]) arg).collect(Collectors.joining(","))); |
| } |
| } |
| |
| return arguments.toArray(new Object[arguments.size()]); |
| } |
| |
| Object[] extend(final Object first, final Object... others) { |
| if (others == null || others.length == 0) { |
| return new Object[] {first}; |
| } |
| |
| final Object[] ret = new Object[1 + others.length]; |
| |
| ret[0] = first; |
| System.arraycopy(others, 0, ret, 1, others.length); |
| |
| return ret; |
| } |
| |
| int indentLevelOf(final String method) { |
| switch (method) { |
| case "rest": |
| return 0; |
| case "post": |
| case "get": |
| case "put": |
| case "patch": |
| case "delete": |
| case "head": |
| case "options": |
| return 1; |
| case "param": |
| indentIntentStack.push(3); |
| return 2; |
| case "endParam": |
| indentIntentStack.pop(); |
| return 2; |
| case "route": |
| indentIntentStack.push(3); |
| return 2; |
| case "endRest": |
| indentIntentStack.pop(); |
| return 2; |
| default: |
| if (indentIntentStack.isEmpty()) { |
| return 2; |
| } |
| return indentIntentStack.peek(); |
| } |
| } |
| |
| String invocationLiteralsFor(final Object[] args) { |
| final StringJoiner literals = new StringJoiner(","); |
| |
| for (final Object arg : args) { |
| if (isPrimitiveOrWrapper(arg.getClass())) { |
| literals.add("$L"); |
| } else if (arg instanceof String) { |
| literals.add("$S"); |
| } else if (arg instanceof Enum) { |
| literals.add("$T.$L"); |
| } else if (arg instanceof String[]) { |
| literals.add("$S"); |
| } |
| } |
| |
| return literals.toString(); |
| } |
| |
| } |