/** * Copyright 2013 Netflix, Inc. * <p/> * Licensed 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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 com.netflix.servo.tag; import com.google.common.collect.Interner; import com.google.common.collect.Interners; /** * Helper functions for working with tags and tag lists. */ public final class Tags { /** * Keep track of the strings that have been used for keys and values. */ private static final Interner<String> STR_CACHE = Interners.newWeakInterner(); /** * Keep track of tags that have been seen before and reuse. */ private static final Interner<Tag> TAG_CACHE = Interners.newWeakInterner(); /** * Intern strings used for tag keys or values. */ public static String intern(String v) { return STR_CACHE.intern(v); } /** * Returns the canonical representation of a tag. */ public static Tag intern(Tag t) { return TAG_CACHE.intern(t); } /** * Interns custom tag types, assumes that basic tags are already interned. This is used to * ensure that we have a common view of tags internally. In particular, different subclasses of * Tag may not be equal even if they have the same key and value. Tag lists should use this to * ensure the equality will work as expected. */ static Tag internCustom(Tag t) { return (t instanceof BasicTag) ? t : newTag(t.getKey(), t.getValue()); } /** * Create a new tag instance. */ public static Tag newTag(String key, String value) { Tag newTag = new BasicTag(intern(key), intern(value)); return intern(newTag); } /** * Parse a string representing a tag. A tag string should have the format {@code key=value}. * Whitespace at the ends of the key and value will be removed. Both the key and value must * have at least one character. * * @param tagString string with encoded tag * @return tag parsed from the string */ public static Tag parseTag(String tagString) { String k; String v; int eqIndex = tagString.indexOf("="); if (eqIndex < 0) { throw new IllegalArgumentException("key and value must be separated by '='"); } k = tagString.substring(0, eqIndex).trim(); v = tagString.substring(eqIndex + 1, tagString.length()).trim(); return newTag(k, v); } /** * Utility class. */ private Tags() { } }