public Tagger(final Class<T> type) { // This would not work properly with localized Tags. // So far we don't have any Enum-based tags that are localized. // But if they appear, this code should prevent those (throw). this.type = type; this.tagName = Validators.findTagNameIn(type); this.cache = CacheBuilder.newBuilder().build(); }
/** * Simple utility method for creating a hashmap out of a set of enum-type tags. * <p> * The key portion of each map entry is extracted from the tag type itself. * * @param values * the enum-type tags we want to convert into a hashmap * @return the completed hashmap */ public static Map<String, String> toMap(final Enum<?>... values) { return Arrays.asList(values).stream().collect(Collectors.toMap( value -> findTagNameIn(value.getClass()), value -> value.name().toLowerCase())); }
/** * Convenience method for checking if we have defined values for all tags passed into the method * * @param taggable * where we look up the tags * @param tagTypes * the type of tags to check * @return true if all of the tags have values, false if at least one is missing */ public static boolean hasValuesFor(final Taggable taggable, final Class<?>... tagTypes) { for (final Class<?> tagType : tagTypes) { if (!taggable.getTag(findTagNameIn(tagType)).isPresent()) { return false; } } return true; }
/** * Reflection version - use when you need to get a few tags, and no caching is necessary. This * method is used by the caching version to populate the cache. * <p> * Helpful method for swizzling an Enum Tag into its possible value if that value is found in * the passed in Taggable parameter. This cuts down on a lot of duplicate code that we had in * each enum-type Tag. * <p> * * @param <T> * the type of enum tag we're parsing * @param tagType * the enum style tag that we want a possible value from * @param taggable * the source of tags and their values * @return an empty optional if the enum isn't a tag, doesn't have a key, the value isn't found * in taggable, or no enum value matches (ignoring case) the tag's value */ public static <T extends Enum<T>> Optional<T> fromAnnotation(final Class<T> tagType, final Taggable taggable) { if (tagType.getDeclaredAnnotation(Tag.class) != null) { return fromHelper(findTagNameIn(tagType), tagType, taggable); } return Optional.empty(); }
/** * Helpful method for swizzling an interface Tag that includes the contents of an enum tag * through the [with] annotation feature into its possible value if that value is found in the * passed in Taggable parameter and the enumType provided is actually listed in the [with] * attribute. * <p> * See the FromEnumTestCase class for an example of how to use this method * * @param <T> * the type of enum tag we're parsing * @param tagType * the interface tag with a [with] attribute that we want a possible value from * @param enumType * the return value type we want a value from * @param taggable * the source of tags and their values * @return an empty optional if the tagType isn't a tag, doesn't have a key, enumType is not * included in tagType's [with] list, the value isn't found in taggable, or no enum * value in enumType matches (ignoring case) the tag's value */ public static <T extends Enum<T>> Optional<T> from(final Class<?> tagType, final Class<T> enumType, final Taggable taggable) { final Tag tag = tagType.getDeclaredAnnotation(Tag.class); if (tag != null && Stream.of(tag.with()).anyMatch(possible -> possible == enumType)) { return fromHelper(findTagNameIn(tagType), enumType, taggable); } return Optional.empty(); }