/* * 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 gobblin.metrics; import java.util.AbstractMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; import com.google.common.base.Function; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; /** * A class representing a dimension or property associated with a {@link Taggable}. * * @param <T> type of the tag value * * @author Yinan Li */ public class Tag<T> extends AbstractMap.SimpleEntry<String, T> { private static final long serialVersionUID = -5083709915031933607L; private static final char KEY_VALUE_SEPARATOR = ':'; /** * Reverse of Tag.toString(). Parses a string of the form "key:value" into a {@link Tag}. * * <p> * If there are multiple ":" in the input string, the key will be the substring up to the first ":", and the * value will be the substring after the first ":". * </p> * * @param tagKeyValue String of the form "key:value". * @return {@link gobblin.metrics.Tag} parsed from input. */ public static Tag<String> fromString(String tagKeyValue) { List<String> splitKeyValue = Splitter.on(KEY_VALUE_SEPARATOR).limit(2).omitEmptyStrings().splitToList(tagKeyValue); if(splitKeyValue.size() == 2) { return new Tag<>(splitKeyValue.get(0), splitKeyValue.get(1)); } else { return null; } } public Tag(String key, T value) { super(key, value); } public Tag(Map.Entry<? extends String, ? extends T> entry) { super(entry); } /** * Converts a {@link Map} of key, value pairs to a {@link List} of {@link Tag}s. Each key, value pair will be used to * create a new {@link Tag}. * * @param tagsMap a {@link Map} of key, value pairs that should be converted into {@link Tag}s * * @return a {@link List} of {@link Tag}s */ public static <T> List<Tag<T>> fromMap(Map<? extends String, T> tagsMap) { ImmutableList.Builder<Tag<T>> tagsBuilder = ImmutableList.builder(); for (Map.Entry<? extends String, T> entry : tagsMap.entrySet()) { tagsBuilder.add(new Tag<>(entry)); } return tagsBuilder.build(); } /** * Converts a {@link List} of {@link Tag}s to a {@link Map} of key, value pairs. * * @param tags a {@link List} of {@link Tag}s that should be converted to key, value pairs * * @return a {@link Map} of key, value pairs */ public static <T> Map<? extends String, T> toMap(List<Tag<T>> tags) { ImmutableMap.Builder<String, T> tagsMapBuilder = ImmutableMap.builder(); for (Tag<T> tag : tags) { tagsMapBuilder.put(tag.getKey(), tag.getValue()); } return tagsMapBuilder.build(); } /** * Converts a {@link List} of wildcard {@link Tag}s to a {@link List} of {@link String} {@link Tag}s. * * @param tags a {@link List} of {@link Tag}s that should be converted to {@link Tag}s with value of type {@link String} * * @return a {@link List} of {@link Tag}s * * @see #tagValueToString(Tag) */ public static List<Tag<String>> tagValuesToString(List<? extends Tag<?>> tags) { return Lists.transform(tags, new Function<Tag<?>, Tag<String>>() { @Nullable @Override public Tag<String> apply(Tag<?> input) { return input == null ? null : Tag.tagValueToString(input); } }); } /** * Converts a wildcard {@link Tag} to a {@link String} {@link Tag}. This method uses the {@link Object#toString()} * method to convert the wildcard type to a {@link String}. * * @param tag a {@link Tag} that should be converted to a {@link Tag} with value of type {@link String} * * @return a {@link Tag} with a {@link String} value */ public static Tag<String> tagValueToString(Tag<?> tag) { return new Tag<>(tag.getKey(), tag.getValue().toString()); } @Override public String toString() { return getKey() + KEY_VALUE_SEPARATOR + getValue(); } }