001package io.avaje.http.generator.core; 002 003import javax.lang.model.element.AnnotationMirror; 004import javax.lang.model.element.AnnotationValue; 005import javax.lang.model.element.Element; 006import javax.lang.model.type.DeclaredType; 007import javax.lang.model.type.TypeKind; 008import javax.lang.model.type.TypeMirror; 009import java.util.ArrayList; 010import java.util.List; 011 012public class Util { 013 014 /** 015 * Return the type removing validation annotations etc. 016 */ 017 public static String typeDef(TypeMirror typeMirror) { 018 if (typeMirror.getKind() == TypeKind.DECLARED) { 019 DeclaredType declaredType = (DeclaredType) typeMirror; 020 return declaredType.asElement().toString(); 021 } else { 022 return typeMirror.toString(); 023 } 024 } 025 026 static String trimPath(String value) { 027 return value.length() <= 1 ? value : trimTrailingSlash(value); 028 } 029 030 private static String trimTrailingSlash(String value) { 031 if (value.endsWith("/")) { 032 return value.substring(0, value.length() - 1); 033 } 034 return value; 035 } 036 037 static String combinePath(String beanPath, String webMethodPath) { 038 StringBuilder sb = new StringBuilder(); 039 if (beanPath != null) { 040 sb.append(beanPath); 041 } 042 if (webMethodPath != null) { 043 if (!webMethodPath.isEmpty() && !webMethodPath.startsWith("/")) { 044 sb.append("/"); 045 } 046 sb.append(trimTrailingSlash(webMethodPath)); 047 } 048 return sb.toString(); 049 } 050 051 public static String shortName(String fullType) { 052 int p = fullType.lastIndexOf('.'); 053 if (p == -1) { 054 return fullType; 055 } else { 056 return fullType.substring(p + 1); 057 } 058 } 059 060 public static String snakeCase(String name) { 061 062 StringBuilder sb = new StringBuilder(name.length() + 5); 063 064 int len = name.length(); 065 for (int i = 0; i < len; i++) { 066 char ch = name.charAt(i); 067 if (Character.isUpperCase(ch)) { 068 if (i > 0) { 069 sb.append("-"); 070 } 071 sb.append(Character.toLowerCase(ch)); 072 } else { 073 sb.append(ch); 074 } 075 } 076 return sb.toString(); 077 } 078 079 public static String initcapSnake(String input) { 080 StringBuilder sb = new StringBuilder(input.length()); 081 int len = input.length(); 082 083 boolean upper = true; 084 085 for (int i = 0; i < len; i++) { 086 char ch = input.charAt(i); 087 if (ch == '-') { 088 sb.append(ch); 089 upper = true; 090 } else { 091 if (upper) { 092 sb.append(Character.toUpperCase(ch)); 093 upper = false; 094 } else { 095 sb.append(ch); 096 } 097 } 098 } 099 return sb.toString(); 100 } 101 102 /** 103 * Find and return the list of roles on the given element. 104 * <p> 105 * This assumes the application uses either <code>@Role</code> annotation 106 * or <code>@PermittedRoles</code> annotation. 107 * </p> 108 * 109 * @param element The bean or method 110 */ 111 public static List<String> findRoles(Element element) { 112 113 List<String> roles = new ArrayList<>(); 114 115 for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { 116 DeclaredType annotationType = annotationMirror.getAnnotationType(); 117 if (isRolesAnnotation(annotationType)) { 118 for (AnnotationValue value : annotationMirror.getElementValues().values()) { 119 String raw = value.toString(); 120 if (raw.startsWith("{")) { 121 raw = raw.substring(1, raw.length() - 1); 122 } 123 for (String singleRole : raw.split(",")) { 124 roles.add(singleRole.trim()); 125 } 126 } 127 } 128 } 129 return roles; 130 } 131 132 private static boolean isRolesAnnotation(DeclaredType annotationType) { 133 String name = annotationType.asElement().getSimpleName().toString(); 134 return name.endsWith("Roles") || name.endsWith("PermittedRoles"); 135 } 136 137 /** 138 * Return the bean property name given the setter method. 139 */ 140 public static String propertyName(String setterMethod) { 141 142 String prop = setterMethod.substring(3); 143 return Character.toLowerCase(prop.charAt(0)) + prop.substring(1); 144 } 145}