All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.zerobuilder.compiler.generate.ZeroUtil Maven / Gradle / Ivy

package net.zerobuilder.compiler.generate;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeVariableName;
import net.zerobuilder.Access;

import javax.lang.model.element.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import static com.squareup.javapoet.MethodSpec.constructorBuilder;
import static java.lang.Character.isUpperCase;
import static java.util.Arrays.copyOf;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toList;

public final class ZeroUtil {

  static final class ClassNames {

    static final ClassName THREAD_LOCAL = ClassName.get(ThreadLocal.class);

    private ClassNames() {
      throw new UnsupportedOperationException("no instances");
    }
  }

  private static final Set reservedWords = new HashSet<>(Arrays.asList(
      "abstract", "continue", "for", "new", "switch", "assert", "default", "if", "package",
      "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements",
      "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum",
      "instanceof", "return", "transient", "catch", "extends", "int", "short", "try", "char", "final",
      "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const",
      "float", "native", "super", "while"));

  public static final CodeBlock emptyCodeBlock = CodeBlock.of("");

  public static String upcase(String s) {
    if (s.isEmpty() || Character.isUpperCase(s.charAt(0))) {
      return s;
    }
    return Character.toUpperCase(s.charAt(0)) + s.substring(1);
  }

  public static String downcase(String s) {
    if (s.length() >= 2 && isUpperCase(s.charAt(1))) {
      return s;
    }
    String lowered = Character.toLowerCase(s.charAt(0)) + s.substring(1);
    if (reservedWords.contains(lowered)) {
      return s;
    }
    return lowered;
  }

  public static CodeBlock statement(String format, Object... args) {
    return CodeBlock.builder().addStatement(format, args).build();
  }

  public static ParameterSpec parameterSpec(TypeName type, String name) {
    return ParameterSpec.builder(type, name).build();
  }

  public static FieldSpec fieldSpec(TypeName type, String name, Modifier... modifiers) {
    return FieldSpec.builder(type, name, modifiers).build();
  }

  public static CodeBlock nullCheck(String varName, String message) {
    return CodeBlock.builder()
        .beginControlFlow("if ($N == null)", varName)
        .addStatement("throw new $T($S)", NullPointerException.class, message)
        .endControlFlow().build();
  }

  public static CodeBlock nullCheck(ParameterSpec parameterSpec) {
    return nullCheck(parameterSpec.name, parameterSpec.name);
  }

  public static CodeBlock nullCheck(ParameterSpec parameterSpec, String message) {
    return nullCheck(parameterSpec.name, message);
  }

  static String distinctFrom(String string, String other) {
    if (string.equals(other)) {
      return 'a' + upcase(string);
    }
    return string;
  }

  public static ClassName rawClassName(TypeName typeName) {
    if (typeName instanceof ClassName) {
      return (ClassName) typeName;
    }
    if (typeName instanceof ParameterizedTypeName) {
      return ((ParameterizedTypeName) typeName).rawType;
    }
    throw new IllegalArgumentException("not a declared type: " + typeName);
  }

  private static List typeArguments(TypeName typeName) {
    if (typeName instanceof ParameterizedTypeName) {
      return ((ParameterizedTypeName) typeName).typeArguments;
    }
    return emptyList();
  }

  /**
   * @param typeName type
   * @return first type argument, if any
   * @throws IllegalArgumentException if type has multiple type arguments
   */
  static Optional onlyTypeArgument(TypeName typeName) {
    List types = typeArguments(typeName);
    switch (types.size()) {
      case 0:
        return Optional.empty();
      case 1:
        return Optional.of(types.get(0));
      default:
        throw new IllegalArgumentException("multiple type arguments");
    }
  }

  public static  List transform(Collection input, Function function) {
    return input.stream().map(function).collect(toList());
  }

  public static 

List

presentInstances(Optional

optional) { if (optional.isPresent()) { return singletonList(optional.get()); } return emptyList(); } public static

List

concat(P first, List list) { List

builder = new ArrayList<>(list.size() + 1); builder.add(first); builder.addAll(list); return builder; } public static

List

concat(List left, List right) { if (left.isEmpty()) { return unmodifiableList(right); } if (right.isEmpty()) { return unmodifiableList(left); } List

builder = new ArrayList<>(left.size() + right.size()); builder.addAll(left); builder.addAll(right); return builder; } public static final Collector, CodeBlock> joinCodeBlocks = joinCodeBlocks(""); public static Collector, CodeBlock> joinCodeBlocks(String delimiter) { return new Collector, CodeBlock>() { @Override public Supplier> supplier() { return ArrayList::new; } @Override public BiConsumer, CodeBlock> accumulator() { return List::add; } @Override public BinaryOperator> combiner() { return (left, right) -> { left.addAll(right); return left; }; } @Override public Function, CodeBlock> finisher() { return blocks -> { if (blocks.isEmpty()) { return emptyCodeBlock; } CodeBlock.Builder builder = CodeBlock.builder(); for (int i = 0; i < blocks.size() - 1; i++) { builder.add(blocks.get(i)); if (!delimiter.isEmpty()) { builder.add(delimiter); } } builder.add(blocks.get(blocks.size() - 1)); return builder.build(); }; } @Override public Set characteristics() { return emptySet(); } }; } public static Collector, List, List> flatList() { return new Collector, List, List>() { @Override public Supplier> supplier() { return ArrayList::new; } @Override public BiConsumer, List> accumulator() { return List::addAll; } @Override public BinaryOperator> combiner() { return (left, right) -> { left.addAll(right); return left; }; } @Override public Function, List> finisher() { return Function.identity(); } @Override public Set characteristics() { return emptySet(); } }; } static Collector, R> listCollector(Function, R> finisher) { return new Collector, R>() { @Override public Supplier> supplier() { return ArrayList::new; } @Override public BiConsumer, E> accumulator() { return List::add; } @Override public BinaryOperator> combiner() { return (left, right) -> { left.addAll(right); return left; }; } @Override public Function, R> finisher() { return finisher; } @Override public Set characteristics() { return emptySet(); } }; } static Supplier memoize(Supplier supplier) { List ref = new ArrayList<>(singletonList(null)); return () -> { R element = ref.get(0); if (element == null) { element = supplier.get(); ref.set(0, element); } return element; }; } public static MethodSpec constructor(Modifier... modifiers) { return constructorBuilder().addModifiers(modifiers).build(); } public static String simpleName(TypeName type) { if (type.isPrimitive() || type == TypeName.VOID) { return ((ClassName) type.box()).simpleName(); } if (type instanceof ClassName) { return ((ClassName) type).simpleName(); } if (type instanceof ParameterizedTypeName) { return ((ParameterizedTypeName) type).rawType.simpleName(); } throw new IllegalArgumentException("unknown kind: " + type); } static int[] createRanking(E[] a, E[] b) { if (a.length != b.length) { throw new IllegalArgumentException("a.length != b.length"); } int[] pos = new int[a.length]; for (int i = 0; i < a.length; i++) { if (b[i].equals(a[i])) { pos[i] = i; } else { pos[i] = indexOf(b, a[i]); } } return pos; } private static int indexOf(E[] b, E el) { for (int i = 0; i < b.length; i++) { if (b[i].equals(el)) { return i; } } throw new IllegalArgumentException("not found: " + el); } static List applyRanking(int[] ranking, List input) { if (input.size() != ranking.length) { throw new IllegalArgumentException("input.size() != ranking.length"); } List result = new ArrayList<>(input.size()); for (int i = 0; i < input.size(); i++) result.add(null); for (int i = 0; i < input.size(); i++) result.set(ranking[i], input.get(i)); return result; } public static TypeName parameterizedTypeName(ClassName raw, List typeVars) { if (typeVars.isEmpty()) { return raw; } return ParameterizedTypeName.get(raw, typeVars.toArray(new TypeVariableName[typeVars.size()])); } private static Modifier[] addModifier(Modifier modifier, Modifier[] modifiers) { for (Modifier m : modifiers) { if (m == modifier) { return modifiers; } } Modifier[] copy = copyOf(modifiers, modifiers.length + 1); copy[modifiers.length] = modifier; return copy; } public static Modifier[] modifiers(Access access, Modifier modifiers) { return access == Access.PUBLIC ? addModifier(Modifier.PUBLIC, new Modifier[]{modifiers}) : access == Access.PRIVATE ? addModifier(Modifier.PRIVATE, new Modifier[]{modifiers}) : new Modifier[]{modifiers}; } public static Modifier[] modifiers(Access access) { return access == Access.PUBLIC ? new Modifier[]{Modifier.PUBLIC} : access == Access.PRIVATE ? new Modifier[]{Modifier.PRIVATE} : new Modifier[0]; } private ZeroUtil() { throw new UnsupportedOperationException("no instances"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy