package restx.annotations.processor; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.base.Splitter; import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Date: 23/10/13 * Time: 10:26 */ public class TypeHelper { private static Pattern PARAMETERIZED_TYPE_PATTERN = Pattern.compile("([^\\<]+)\\<(.+)\\>"); private static Pattern guavaOptionalPattern = Pattern.compile("\\Q" + Optional.class.getName() + "<\\E(.+)>"); private static Pattern java8OptionalPattern = Pattern.compile("\\Qjava.util.Optional<\\E(.+)>"); private static Set<String> RAW_TYPES_STR = Sets.newHashSet("byte", "short", "int", "long", "float", "double", "boolean", "char"); static String getTypeExpressionFor(String type) { Matcher matcher = PARAMETERIZED_TYPE_PATTERN.matcher(type); if (matcher.matches()) { String rawType = matcher.group(1); return "Types.newParameterizedType(" + rawType + ".class, " + getTypeExpressionFor(matcher.group(2)) + ")"; } else { if (type.contains(",")) { List<String> pTypes = new ArrayList<>(); for (String pType : Splitter.on(",").trimResults().split(type)) { pTypes.add(getTypeExpressionFor(pType)); } return Joiner.on(", ").join(pTypes); } else { return type + ".class"; } } } static boolean isParameterizedType(String type) { return type.contains("<"); } static String rawTypeFrom(String type) { return isParameterizedType(type)?type.substring(0, type.indexOf("<")):type; } static String getTypeReferenceExpressionFor(String type) { return RAW_TYPES_STR.contains(type) ? type + ".class" : "new TypeReference<" + type + ">(){}"; } public static class OptionalMatchingType { public enum Type {GUAVA, JAVA8, NONE} private final Type optionalType; private final String underlyingType; protected OptionalMatchingType(Type optionalType, String underlyingType) { this.optionalType = optionalType; this.underlyingType = underlyingType; } public static OptionalMatchingType guava(String underlyingType) { return new OptionalMatchingType(Type.GUAVA, underlyingType); } public static OptionalMatchingType java8(String underlyingType) { return new OptionalMatchingType(Type.JAVA8, underlyingType); } public static OptionalMatchingType none(String underlyingType) { return new OptionalMatchingType(Type.NONE, underlyingType); } public Type getOptionalType() { return optionalType; } public String getUnderlyingType() { return underlyingType; } } public static OptionalMatchingType optionalMatchingTypeOf(String type) { Matcher guavaOptionalMatcher = guavaOptionalPattern.matcher(type); if (guavaOptionalMatcher.matches()) { return OptionalMatchingType.guava(guavaOptionalMatcher.group(1)); } Matcher java8OptionalMatcher = java8OptionalPattern.matcher(type); if (java8OptionalMatcher.matches()) { return OptionalMatchingType.java8(java8OptionalMatcher.group(1)); } return OptionalMatchingType.none(type); } }