text:
// This file is part of OpenTSDB.
// Copyright (C) 2010-2012  The OpenTSDB Authors.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or (at your
// option) any later version.  This program is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
// General Public License for more details.  You should have received a copy
// of the GNU Lesser General Public License along with this program.  If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ImmutableMap;

/**
 * OpenTSDB Configuration Class
 *
 * This handles all of the user configurable variables for a TSD. On
 * initialization default values are configured for all variables. Then
 * implementations should call the {@link #loadConfig()} methods to search for a
 * default configuration or try to load one provided by the user.
 *
 * To add a configuration, simply set a default value in {@link #setDefaults()}.
 * Wherever you need to access the config value, use the proper helper to fetch
 * the value, accounting for exceptions that may be thrown if necessary.
 *
 * The get<type> number helpers will return NumberFormatExceptions if the
 * requested property is null or unparseable. The {@link #getString(String)}
 * helper will return a NullPointerException if the property isn't found.
 * <p>
 * Plugins can extend this class and copy the properties from the main
 * TSDB.config instance. Plugins should never change the main TSD's config
 * properties, rather a plugin should use the Config(final Config parent)
 * constructor to get a copy of the parent's properties and then work with the
 * values locally.
 * @since 2.0
 */
public class Config {
  private static final Logger LOG = LoggerFactory.getLogger(Config.class);

  /** Flag to determine if we're running under Windows or not */
  public static final boolean IS_WINDOWS =
      System.getProperty("os.name", "").contains("Windows");

  // These are accessed often so need a set address for fast access (faster
  // than accessing the map. Their value will be changed when the config is
  // loaded
  // NOTE: edit the setDefaults() method if you add a public field

  /** tsd.core.auto_create_metrics */
  private boolean auto_metric = false;

  /** tsd.core.auto_create_tagk */
  private boolean auto_tagk = true;

  /** tsd.core.auto_create_tagv */
  private boolean auto_tagv = true;

  /** tsd.storage.enable_compaction */
  private boolean enable_compactions = true;

  /** tsd.storage.enable_appends */
  private boolean enable_appends = false;

  /** tsd.storage.repair_appends */
  private boolean repair_appends = false;

  /** tsd.core.meta.enable_realtime_ts */
  private boolean enable_realtime_ts = false;

  /** tsd.core.meta.enable_realtime_uid */
  private boolean enable_realtime_uid = false;

  /** tsd.core.meta.enable_tsuid_incrementing */
  private boolean enable_tsuid_incrementing = false;

  /** tsd.core.meta.enable_tsuid_tracking */
  private boolean enable_tsuid_tracking = false;

  /** tsd.http.request.enable_chunked */
  private boolean enable_chunked_requests = false;

  /** tsd.storage.fix_duplicates */
  private boolean fix_duplicates = false;

  /** tsd.http.request.max_chunk */
  private int max_chunked_requests = 4096;

  /** tsd.core.tree.enable_processing */
  private boolean enable_tree_processing = false;

  /** tsd.storage.hbase.scanner.maxNumRows */
  private int scanner_max_num_rows = 128;

  // MARK(zhoujiagen) 自定义配置参数
  /** tsd.extension.ganglia.host */
  private String ganglia_host = "localhost";
  /** tsd.extension.ganglia.port */
  private int ganglia_port = 8649;

  private String kafkaPropertiesFile;
  private Properties kafkaProperties;

  /**
   * The list of properties configured to their defaults or modified by users
   */
  protected final HashMap<String, String> properties =
    new HashMap<String, String>(); // MARK(zhoujiagen) 实际配置属性以这个为准

  /** Holds default values for the config */
  protected static final HashMap<String, String> default_map =
    new HashMap<String, String>();

  /** Tracks the location of the file that was actually loaded */
  protected String config_location;

  /**
   * Constructor that initializes default configuration values. May attempt to
   * search for a config file if configured.
   * @param auto_load_config When set to true, attempts to search for a config
   *          file in the default locations
   * @throws IOException Thrown if unable to read or parse one of the default
   *           config files
   */
  public Config(final boolean auto_load_config) throws IOException {
    if (auto_load_config) {
      loadConfig();
    }
    setDefaults();
  }

  /**
   * Constructor that initializes default values and attempts to load the given
   * properties file
   * @param file Path to the file to load
   * @throws IOException Thrown if unable to read or parse the file
   */
  public Config(final String file) throws IOException {
    loadConfig(file);
    setDefaults();
  }

  /**
   * Constructor for plugins or overloaders who want a copy of the parent
   * properties but without the ability to modify them
   *
   * This constructor will not re-read the file, but it will copy the location
   * so if a child wants to reload the properties periodically, they may do so
   * @param parent Parent configuration object to load from
   */
  public Config(final Config parent) {
    // copy so changes to the local props by the plugin don't affect the master
    properties.putAll(parent.properties);
    config_location = parent.config_location;
    setDefaults();
  }

  /** @return The file that generated this config. May be null */
  public String configLocation() {
    return config_location;
  }

  /** @return the auto_metric value */
  public boolean auto_metric() {
    return auto_metric;
  }

  /** @return the auto_tagk value */
  public boolean auto_tagk() {
    return auto_tagk;
  }

  /** @return the auto_tagv value */
  public boolean auto_tagv() {
    return auto_tagv;
  }

  /** @param auto_metric whether or not to auto create metrics */
  public void setAutoMetric(boolean auto_metric) {
    this.auto_metric = auto_metric;
    properties.put("tsd.core.auto_create_metrics",
        Boolean.toString(auto_metric));
  }

  /** @return the enable_compaction value */
  public boolean enable_compactions() {
    return enable_compactions;
  }

  /** @return whether or not to write data in the append format */
  public boolean enable_appends() {
    return enable_appends;
  }

  /** @return whether or not to re-write appends with duplicates or out of order
   * data when queried. */
  public boolean repair_appends() {
    return repair_appends;
  }

  /** @return whether or not to record new TSMeta objects in real time */
  public boolean enable_realtime_ts() {
    return enable_realtime_ts;
  }

  /** @return whether or not record new UIDMeta objects in real time */
  public boolean enable_realtime_uid() {
    return enable_realtime_uid;
  }

  /** @return whether or not to increment TSUID counters */
  public boolean enable_tsuid_incrementing() {
    return enable_tsuid_incrementing;
  }

  /** @return whether or not to record a 1 for every TSUID */
  public boolean enable_tsuid_tracking() {
    return enable_tsuid_tracking;
  }

  /** @return maximum number of rows to be fetched per round trip while scanning HBase */
  public int scanner_maxNumRows() {
    return scanner_max_num_rows;
  }

  /** @return whether or not chunked requests are supported */
  public boolean enable_chunked_requests() {
    return enable_chunked_requests;
  }

  /** @return max incoming chunk size in bytes */
  public int max_chunked_requests() {
    return max_chunked_requests;
  }

  /** @return true if duplicate values should be fixed */
  public boolean fix_duplicates() {
    return fix_duplicates;
  }

  /** @param fix_duplicates true if duplicate values should be fixed */
  public void setFixDuplicates(final boolean fix_duplicates) {
    this.fix_duplicates = fix_duplicates;
  }

  /** @return whether or not to process new or updated TSMetas through trees */
  public boolean enable_tree_processing() {
    return enable_tree_processing;
  }

  // MARK(zhoujiagen) Ganglia配置属性getter
  public String ganglia_host() {
      return ganglia_host;
  }

  public int ganglia_port() {
      return ganglia_port;
  }

  public Properties kafkaProperties() {
    return kafkaProperties;
  }

  /**
   * Allows for modifying properties after creation or loading.
   *
   * WARNING: This should only be used on initialization and is meant for
   * command line overrides. Also note that it will reset all static config
   * variables when called.
   *
   * @param property The name of the property to override
   * @param value The value to store
   */
  public void overrideConfig(final String property, final String value) {
    properties.put(property, value);
    loadStaticVariables();
  }

  /**
   * Returns the given property as a String
   * @param property The property to load
   * @return The property value as a string
   * @throws NullPointerException if the property did not exist
   */
  public final String getString(final String property) {
    return properties.get(property);
  }

  /**
   * Returns the given property as an integer
   * @param property The property to load
   * @return A parsed integer or an exception if the value could not be parsed
   * @throws NumberFormatException if the property could not be parsed
   * @throws NullPointerException if the property did not exist
   */
  public final int getInt(final String property) {
    return Integer.parseInt(sanitize(properties.get(property)));
  }

  /**
   * Returns the given string trimed or null if is null
   * @param string The string be trimmed of
   * @return The string trimed or null
  */
  private final String sanitize(final String string) {
    if (string == null) {
      return null;
    }

    return string.trim();
  }

  /**
   * Returns the given property as a short
   * @param property The property to load
   * @return A parsed short or an exception if the value could not be parsed
   * @throws NumberFormatException if the property could not be parsed
   * @throws NullPointerException if the property did not exist
   */
  public final short getShort(final String property) {
    return Short.parseShort(sanitize(properties.get(property)));
  }

  /**
   * Returns the given property as a long
   * @param property The property to load
   * @return A parsed long or an exception if the value could not be parsed
   * @throws NumberFormatException if the property could not be parsed
   * @throws NullPointerException if the property did not exist
   */
  public final long getLong(final String property) {
    return Long.parseLong(sanitize(properties.get(property)));
  }

  /**
   * Returns the given property as a float
   * @param property The property to load
   * @return A parsed float or an exception if the value could not be parsed
   * @throws NumberFormatException if the property could not be parsed
   * @throws NullPointerException if the property did not exist
   */
  public final float getFloat(final String property) {
    return Float.parseFloat(sanitize(properties.get(property)));
  }

  /**
   * Returns the given property as a double
   * @param property The property to load
   * @return A parsed double or an exception if the value could not be parsed
   * @throws NumberFormatException if the property could not be parsed
   * @throws NullPointerException if the property did not exist
   */
  public final double getDouble(final String property) {
    return Double.parseDouble(sanitize(properties.get(property)));
  }

  /**
   * Returns the given property as a boolean
   *
   * Property values are case insensitive and the following values will result
   * in a True return value: - 1 - True - Yes
   *
   * Any other values, including an empty string, will result in a False
   *
   * @param property The property to load
   * @return A parsed boolean
   * @throws NullPointerException if the property was not found
   */
  public final boolean getBoolean(final String property) {
    final String val = properties.get(property).trim().toUpperCase();
    if (val.equals("1"))
      return true;
    if (val.equals("TRUE"))
      return true;
    if (val.equals("YES"))
      return true;
    return false;
  }

  /**
   * Returns the directory name, making sure the end is an OS dependent slash
   * @param property The property to load
   * @return The property value with a forward or back slash appended or null
   * if the property wasn't found or the directory was empty.
   */
  public final String getDirectoryName(final String property) {
    String directory = properties.get(property);
    if (directory == null || directory.isEmpty()){
      return null;
    }
    if (IS_WINDOWS) {
      // Windows swings both ways. If a forward slash was already used, we'll
      // add one at the end if missing. Otherwise use the windows default of \
      if (directory.charAt(directory.length() - 1) == '\\' ||
          directory.charAt(directory.length() - 1) == '/') {
        return directory;
      }
      if (directory.contains("/")) {
        return directory + "/";
      }
      return directory + "\\";
    }
    if (directory.contains("\\")) {
      throw new IllegalArgumentException(
          "Unix path names cannot contain a back slash");
    }

    if (directory == null || directory.isEmpty()){
    	return null;
    }

    if (directory.charAt(directory.length() - 1) == '/') {
      return directory;
    }
    return directory + "/";
  }

  /**
   * Determines if the given propery is in the map
   * @param property The property to search for
   * @return True if the property exists and has a value, not an empty string
   */
  public final boolean hasProperty(final String property) {
    final String val = properties.get(property);
    if (val == null)
      return false;
    if (val.isEmpty())
      return false;
    return true;
  }

  /**
   * Returns a simple string with the configured properties for debugging
   * @return A string with information about the config
   */
  public final String dumpConfiguration() {
    if (properties.isEmpty())
      return "No configuration settings stored";

    StringBuilder response = new StringBuilder("TSD Configuration:\n");
    response.append("File [" + config_location + "]\n");
    int line = 0;
    for (Map.Entry<String, String> entry : properties.entrySet()) {
      if (line > 0) {
        response.append("\n");
      }
      response.append("Key [" + entry.getKey() + "]  Value [");
      if (entry.getKey().toUpperCase().contains("PASS")) {
         response.append("********");
      } else {
        response.append(entry.getValue());
      }
      response.append("]");
      line++;
    }
    return response.toString();
  }

  /** @return An immutable copy of the configuration map */
  public final Map<String, String> getMap() {
    return ImmutableMap.copyOf(properties);
  }

  /**
   * set enable_compactions to true
   */
  public final void enableCompactions() {
    this.enable_compactions = true;
  }

  /**
   * set enable_compactions to false
   */
  public final void disableCompactions() {
    this.enable_compactions = false;
  }

  /**
   * Loads default entries that were not provided by a file or command line
   *
   * This should be called in the constructor
   */
  protected void setDefaults() {
    // map.put("tsd.network.port", ""); // does not have a default, required
    // map.put("tsd.http.cachedir", ""); // does not have a default, required
    // map.put("tsd.http.staticroot", ""); // does not have a default, required
    default_map.put("tsd.mode", "rw");
    default_map.put("tsd.no_diediedie", "false");
    default_map.put("tsd.network.bind", "0.0.0.0");
    default_map.put("tsd.network.worker_threads", "");
    default_map.put("tsd.network.async_io", "true");
    default_map.put("tsd.network.tcp_no_delay", "true");
    default_map.put("tsd.network.keep_alive", "true");
    default_map.put("tsd.network.reuse_address", "true");
    default_map.put("tsd.core.auto_create_metrics", "false");
    default_map.put("tsd.core.auto_create_tagks", "true");
    default_map.put("tsd.core.auto_create_tagvs", "true");
    default_map.put("tsd.core.connections.limit", "0");
    default_map.put("tsd.core.enable_api", "true");
    default_map.put("tsd.core.enable_ui", "true");
    default_map.put("tsd.core.meta.enable_realtime_ts", "false");
    default_map.put("tsd.core.meta.enable_realtime_uid", "false");
    default_map.put("tsd.core.meta.enable_tsuid_incrementing", "false");
    default_map.put("tsd.core.meta.enable_tsuid_tracking", "false");
    default_map.put("tsd.core.meta.cache.enable", "false");
    default_map.put("tsd.core.plugin_path", "");
    default_map.put("tsd.core.socket.timeout", "0");
    default_map.put("tsd.core.tree.enable_processing", "false");
    default_map.put("tsd.core.preload_uid_cache", "false");
    default_map.put("tsd.core.preload_uid_cache.max_entries", "300000");
    default_map.put("tsd.core.storage_exception_handler.enable", "false");
    default_map.put("tsd.core.uid.random_metrics", "false");
    default_map.put("tsd.query.filter.expansion_limit", "4096");
    default_map.put("tsd.query.skip_unresolved_tagvs", "false");
    default_map.put("tsd.query.allow_simultaneous_duplicates", "true");
    default_map.put("tsd.query.enable_fuzzy_filter", "true");
    default_map.put("tsd.rtpublisher.enable", "false");
    default_map.put("tsd.rtpublisher.plugin", "");
    default_map.put("tsd.search.enable", "false");
    default_map.put("tsd.search.plugin", "");
    default_map.put("tsd.stats.canonical", "false");
    default_map.put("tsd.startup.enable", "false");
    default_map.put("tsd.startup.plugin", "");
    default_map.put("tsd.storage.hbase.scanner.maxNumRows", "128");
    default_map.put("tsd.storage.fix_duplicates", "false");
    default_map.put("tsd.storage.flush_interval", "1000");
    default_map.put("tsd.storage.hbase.data_table", "tsdb");
    default_map.put("tsd.storage.hbase.uid_table", "tsdb-uid");
    default_map.put("tsd.storage.hbase.tree_table", "tsdb-tree");
    default_map.put("tsd.storage.hbase.meta_table", "tsdb-meta");
    default_map.put("tsd.storage.hbase.zk_quorum", "localhost");
    default_map.put("tsd.storage.hbase.zk_basedir", "/hbase");
    default_map.put("tsd.storage.hbase.prefetch_meta", "false");
    default_map.put("tsd.storage.enable_appends", "false");
    default_map.put("tsd.storage.repair_appends", "false");
    default_map.put("tsd.storage.enable_compaction", "true");
    default_map.put("tsd.storage.compaction.flush_interval", "10");
    default_map.put("tsd.storage.compaction.min_flush_threshold", "100");
    default_map.put("tsd.storage.compaction.max_concurrent_flushes", "10000");
    default_map.put("tsd.storage.compaction.flush_speed", "2");
    default_map.put("tsd.timeseriesfilter.enable", "false");
    default_map.put("tsd.uidfilter.enable", "false");
    default_map.put("tsd.core.stats_with_port", "false");
    default_map.put("tsd.http.show_stack_trace", "true");
    default_map.put("tsd.http.query.allow_delete", "false");
    default_map.put("tsd.http.request.enable_chunked", "false");
    default_map.put("tsd.http.request.max_chunk", "4096");
    default_map.put("tsd.http.request.cors_domains", "");
    default_map.put("tsd.http.request.cors_headers", "Authorization, "
      + "Content-Type, Accept, Origin, User-Agent, DNT, Cache-Control, "
      + "X-Mx-ReqToken, Keep-Alive, X-Requested-With, If-Modified-Since");
    default_map.put("tsd.query.timeout", "0");

    for (Map.Entry<String, String> entry : default_map.entrySet()) {
      if (!properties.containsKey(entry.getKey()))
        properties.put(entry.getKey(), entry.getValue());
    }

    loadStaticVariables();
  }

  /**
   * Searches a list of locations for a valid opentsdb.conf file
   *
   * The config file must be a standard JAVA properties formatted file. If none
   * of the locations have a config file, then the defaults or command line
   * arguments will be used for the configuration
   *
   * Defaults for Linux based systems are: ./opentsdb.conf /etc/opentsdb.conf
   * /etc/opentsdb/opentdsb.conf /opt/opentsdb/opentsdb.conf
   *
   * @throws IOException Thrown if there was an issue reading a file
   */
  protected void loadConfig() throws IOException {
    if (config_location != null && !config_location.isEmpty()) {
      loadConfig(config_location);
      return;
    }

    final ArrayList<String> file_locations = new ArrayList<String>();

    // search locally first
    file_locations.add("opentsdb.conf");

    // add default locations based on OS
    if (System.getProperty("os.name").toUpperCase().contains("WINDOWS")) {
      file_locations.add("C:\\Program Files\\opentsdb\\opentsdb.conf");
      file_locations.add("C:\\Program Files (x86)\\opentsdb\\opentsdb.conf");
    } else {
      file_locations.add("/etc/opentsdb.conf");
      file_locations.add("/etc/opentsdb/opentsdb.conf");
      file_locations.add("/opt/opentsdb/opentsdb.conf");
    }

    for (String file : file_locations) {
      try {
        FileInputStream file_stream = new FileInputStream(file);
        Properties props = new Properties();
        props.load(file_stream);

        // load the hash map
        loadHashMap(props);
      } catch (Exception e) {
        // don't do anything, the file may be missing and that's fine
        LOG.debug("Unable to find or load " + file, e);
        continue;
      }

      // no exceptions thrown, so save the valid path and exit
      LOG.info("Successfully loaded configuration file: " + file);
      config_location = file;
      return;
    }

    LOG.info("No configuration found, will use defaults");
  }

  /**
   * Attempts to load the configuration from the given location
   * @param file Path to the file to load
   * @throws IOException Thrown if there was an issue reading the file
   * @throws FileNotFoundException Thrown if the config file was not found
   */
  protected void loadConfig(final String file) throws FileNotFoundException,
      IOException {
    final FileInputStream file_stream = new FileInputStream(file);
    try {
      final Properties props = new Properties();
      props.load(file_stream);

      // load the hash map
      loadHashMap(props);

      // no exceptions thrown, so save the valid path and exit
      LOG.info("Successfully loaded configuration file: " + file);
      config_location = file;
    } finally {
      file_stream.close();
    }
  }

  /**
   * Loads the static class variables for values that are called often. This
   * should be called any time the configuration changes.
   */
  protected void loadStaticVariables() {
    auto_metric = this.getBoolean("tsd.core.auto_create_metrics");
    auto_tagk = this.getBoolean("tsd.core.auto_create_tagks");
    auto_tagv = this.getBoolean("tsd.core.auto_create_tagvs");
    enable_compactions = this.getBoolean("tsd.storage.enable_compaction");
    enable_appends = this.getBoolean("tsd.storage.enable_appends");
    repair_appends = this.getBoolean("tsd.storage.repair_appends");
    enable_chunked_requests = this.getBoolean("tsd.http.request.enable_chunked");
    enable_realtime_ts = this.getBoolean("tsd.core.meta.enable_realtime_ts");
    enable_realtime_uid = this.getBoolean("tsd.core.meta.enable_realtime_uid");
    enable_tsuid_incrementing =
      this.getBoolean("tsd.core.meta.enable_tsuid_incrementing");
    enable_tsuid_tracking =
      this.getBoolean("tsd.core.meta.enable_tsuid_tracking");
    if (this.hasProperty("tsd.http.request.max_chunk")) {
      max_chunked_requests = this.getInt("tsd.http.request.max_chunk");
    }
    enable_tree_processing = this.getBoolean("tsd.core.tree.enable_processing");
    fix_duplicates = this.getBoolean("tsd.storage.fix_duplicates");
    scanner_max_num_rows = this.getInt("tsd.storage.hbase.scanner.maxNumRows");

    // MARK(zhoujiagen) Ganglia配置
    ganglia_host = this.getString("tsd.extension.ganglia.host");
    ganglia_port = this.getInt("tsd.extension.ganglia.port");

    // MARK(zhoujiagen) Kafka客户端配置
    kafkaPropertiesFile = this.getString("tsd.extension.plugin.kakfa.file");
    kafkaProperties = new Properties();
    try (Reader reader = new FileReader(kafkaPropertiesFile);) {
      kafkaProperties.load(reader);
    } catch (FileNotFoundException e) {
      LOG.error("load kafka properties file failed", e);
    } catch (IOException e) {
      LOG.error("load kafka properties file failed", e);
    }
  }

  /**
   * Called from {@link #loadConfig} to copy the properties into the hash map
   * Tsuna points out that the Properties class is much slower than a hash
   * map so if we'll be looking up config values more than once, a hash map
   * is the way to go
   * @param props The loaded Properties object to copy
   */
  private void loadHashMap(final Properties props) {
    properties.clear();

    @SuppressWarnings("rawtypes")
    Enumeration e = props.propertyNames();
    while (e.hasMoreElements()) {
      String key = (String) e.nextElement();
      properties.put(key, props.getProperty(key));
    }
  }

}


text:
package com.thecoffeine.virtuoso.music.model.entity;

import com.thecoffeine.virtuoso.module.model.AbstractModel;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.constraints.NotNull;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Tests for VideoType
 * @see VideoType
 *
 * @version 1.0
 */
public class VideoTypeTest extends AbstractModel {

    /**
     * Test field validation for entity filled correct
     */
    @Test
    public void testVideoTypeFieldsSuccess() {

        Set< ConstraintViolation< VideoType > > constraintViolationSet;

        //- Success -//
        //- Create entity -//
        VideoType videoTypeSuccess = new VideoType(
            "POLKA",
            "Polka",
            "Ukrainian polka"
        );

        //- Validate -//
        constraintViolationSet = validator.validate( videoTypeSuccess );

        assertEquals( 0, constraintViolationSet.size() );
    }

    /**
     * Test field validation for entity filled incorrect
     */
    @Test
    public void testVideoTypeFieldsFailure() {

        Set< ConstraintViolation< VideoType > > constraintViolationSet;

        //- Failure -//
        //- Create entity -//
        VideoType videoTypeFailure = new VideoType(
            null,
            null,
            "Ukrainian polka"
        );

        //- Validate -//
        constraintViolationSet = validator.validate( videoTypeFailure );

        assertEquals( 4, constraintViolationSet.size() );
        for ( ConstraintViolation< VideoType > constraintViolation : constraintViolationSet ) {
            //- Property name -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "code" );
                    add( "title" );
                }}.contains(
                    this.getPropertyName(
                        constraintViolation.getPropertyPath()
                    )
                )
            );
            //- Annotation type -//
            assertTrue(
                new ArrayList< Class >() {{
                    add( NotNull.class );
                    add( NotEmpty.class );
                }}.contains(
                    constraintViolation.getConstraintDescriptor().getAnnotation().annotationType()
                )
            );
            //- Message -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "may not be null" );
                    add( "may not be empty" );
                }}.contains( constraintViolation.getMessage() )
            );
        }
    }

    /**
     * Test of length constraints
     */
    @Test
    public void testLengthConstraint() {

        Set< ConstraintViolation< VideoType > > constraintViolationSet;

        //- Failure: Incorrect length -//
        //- Create entity -//
        VideoType videoTypeFailureLength = new VideoType(
            "12345678901234567",
            "123456789012345678901234567890123"
        );

        //- Validate -//
        constraintViolationSet = validator.validate( videoTypeFailureLength );

        assertEquals( 2, constraintViolationSet.size() );

        for ( ConstraintViolation< VideoType > constraintViolation : constraintViolationSet ) {
            //- Property name -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "code" );
                    add( "title" );
                }}.contains(
                    this.getPropertyName(
                        constraintViolation.getPropertyPath()
                    )
                )
            );
            //- Annotation type -//
            assertTrue(
                new ArrayList< Class >() {{
                    add( Length.class );
                }}.contains(
                    constraintViolation.getConstraintDescriptor().getAnnotation().annotationType()
                )
            );
            //- Message -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "length must be between 0 and 16" );
                    add( "length must be between 0 and 32" );
                }}.contains( constraintViolation.getMessage() )
            );
        }
    }

    /*
    * Test field validation for entity failure( empty )
    */
    @Test
    public void testAccessFieldEmpty() {

        Set< ConstraintViolation< VideoType > > constraintViolationSet;

        //- Failure: fields is empty-//
        //- Create entity -//
        VideoType videoTypeFailureEmpty = new VideoType(
            "",
            ""
        );

        //- Validate -//
        constraintViolationSet = validator.validate( videoTypeFailureEmpty );

        assertEquals( 2, constraintViolationSet.size() );

        for ( ConstraintViolation< VideoType > constraintViolation : constraintViolationSet ) {
            //- Property name -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "code" );
                    add( "title" );
                }}.contains(
                    this.getPropertyName(
                        constraintViolation.getPropertyPath()
                    )
                )
            );
            //- Annotation type -//
            assertTrue(
                new ArrayList< Class >() {{
                    add( NotEmpty.class );
                }}.contains(
                    constraintViolation.getConstraintDescriptor().getAnnotation().annotationType()
                )
            );
            //- Message -//
            assertTrue(
                new ArrayList< String >() {{
                    add( "may not be empty" );
                }}.contains( constraintViolation.getMessage() )
            );
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
/**
 * 刘飞
 */
$(document).ready(function() {
	$(".select2").select2();
	$(".search-btn").click(function() {
		var systemId = $(".systemId-value").val();
		if (systemId == null || systemId == "") {
			alert("请输入应用名称");
			return;
		}
		$.ajax({
			  type: 'POST',
			  url: "rpc/selector/getting",
			  data: {
				  systemId : systemId
			  },
			  beforeSend : function() {},
			  success: function(data,textStatus,jqXHR) {
				  var systemId = data.systemId;
				  var transportProtocol = data.transportProtocol;
				  $(".exchange").attr("data-systemId", systemId);
				  $(".title").html("应用" + systemId + "当前使用协议为 : " + transportProtocol);
				  if (transportProtocol == "AMQP") {
					  var optHtml = '<option value="AMQP" selected="selected">AMQP</option><option value="WSOCK">WSOCK</option>';
					  $(".exchange").html(optHtml);
				  }
				  if (transportProtocol == "WSOCK") {
					  var optHtml = '<option value="WSOCK" selected="selected">WSOCK</option><option value="AMQP">AMQP</option>';
					  $(".exchange").html(optHtml);
				  }
			  },
			  dataType: "json"
		});
	});
	$(".exchange").on("change", function(){
		var protocol = $(".exchange").val();
		var systemId = $(".exchange").attr("data-systemId");
		if (!confirm("确定要将应用" + systemId + "传输协议切换为[" + protocol + "]吗?")) {
			return;
		}
		$.ajax({
			  type: 'POST',
			  url: "rpc/selector/setting",
			  data: {
				  systemId : systemId,
				  protocol : protocol
			  },
			  beforeSend : function() {},
			  success: function(data, textStatus, jqXHR) {
				  var nonpermission = data.nonpermission;
				  if (nonpermission != null && nonpermission != "") {
					  alert(nonpermission);
					  return;
				  }
				  var systemId = data.systemId;
				  var transportProtocol = data.transportProtocol;
				  $(".title").html("应用" + systemId + "当前使用协议为 : " + transportProtocol);
				  if (transportProtocol == "AMQP") {
					  var optHtml = '<option value="AMQP" selected="selected">AMQP</option><option value="WSOCK">WSOCK</option>';
					  $(".exchange").html(optHtml);
				  }
				  if (transportProtocol == "WSOCK") {
					  var optHtml = '<option value="WSOCK" selected="selected">WSOCK</option><option value="AMQP">AMQP</option>';
					  $(".exchange").html(optHtml);
				  }
			  },
			  dataType: "json"
		});
	});
});


text:
class StrategyFactory(object):
    def get_player(self, hand):
        pass


text:
layout: docs
title: Navs
description: Documentation and examples for how to use Bootstrap's included navigation components.
group: components
toc: true
---

## Base nav

Navigation available in Bootstrap share general markup and styles, from the base `.nav` class to the active and disabled states. Swap modifier classes to switch between each style.

The base `.nav` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling.

{{< callout info >}}
The base `.nav` component does not include any `.active` state. The following examples include the class, mainly to demonstrate that this particular class does not trigger any special styling.
{{< /callout >}}

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

Classes are used throughout, so your markup can be super flexible. Use `<ul>`s like above, `<ol>` if the order of your items is important, or roll your own with a `<nav>` element. Because the `.nav` uses `display: flex`, the nav links behave the same as nav items would, but without the extra markup.

{{< example >}}

  Active
  Link
  Link
  Disabled

{{< /example >}}

## Available styles

Change the style of `.nav`s component with modifiers and utilities. Mix and match as needed, or build your own.

### Horizontal alignment

Change the horizontal alignment of your nav with [flexbox utilities]({{< docsref "/layout/grid#horizontal-alignment" >}}). By default, navs are left-aligned, but you can easily change them to center or right aligned.

Centered with `.justify-content-center`:

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

Right-aligned with `.justify-content-end`:

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

### Vertical

Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

As always, vertical navigation is possible without `<ul>`s, too.

{{< example >}}

  Active
  Link
  Link
  Disabled

{{< /example >}}

### Tabs

Takes the basic nav from above and adds the `.nav-tabs` class to generate a tabbed interface. Use them to create tabbable regions with our [tab JavaScript plugin](#javascript-behavior).

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

### Pills

Take that same HTML, but use `.nav-pills` instead:

{{< example >}}

    Active

    Link

    Link

    Disabled

{{< /example >}}

### Fill and justify

Force your `.nav`'s contents to extend the full available width one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `.nav-fill`. Notice that all horizontal space is occupied, but not every nav item has the same width.

{{< example >}}

    Active

    Much longer nav link

    Link

    Disabled

{{< /example >}}

When using a `<nav>`-based navigation, you can safely omit `.nav-item` as only `.nav-link` is required for styling `<a>` elements.

{{< example >}}

  Active
  Much longer nav link
  Link
  Disabled

{{< /example >}}

For equal-width elements, use `.nav-justified`. All horizontal space will be occupied by nav links, but unlike the `.nav-fill` above, every nav item will be the same width.

{{< example >}}

    Active

    Much longer nav link

    Link

    Disabled

{{< /example >}}

Similar to the `.nav-fill` example using a `<nav>`-based navigation.

{{< example >}}

  Active
  Much longer nav link
  Link
  Disabled

{{< /example >}}
## Working with flex utilities

If you need responsive nav variations, consider using a series of [flexbox utilities]({{< docsref "/utilities/flex" >}}). While more verbose, these utilities offer greater customization across responsive breakpoints. In the example below, our nav will be stacked on the lowest breakpoint, then adapt to a horizontal layout that fills the available width starting from the small breakpoint.

{{< example >}}

  Active
  Longer nav link
  Link
  Disabled

{{< /example >}}

## Regarding accessibility

If you're using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the `<ul>`, or wrap a `<nav>` element around the whole navigation. Do not add the role to the `<ul>` itself, as this would prevent it from being announced as an actual list by assistive technologies.

Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [WAI ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example.

## Using dropdowns

Add dropdown menus with a little extra HTML and the [dropdowns JavaScript plugin]({{< docsref "/components/dropdowns#usage" >}}).

### Tabs with dropdowns

{{< example >}}

    Active

    Dropdown

      Action
      Another action
      Something else here

      Separated link

    Link

    Disabled

{{< /example >}}

### Pills with dropdowns

{{< example >}}

    Active

    Dropdown

      Action
      Another action
      Something else here

      Separated link

    Link

    Disabled

{{< /example >}}

## JavaScript behavior

Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our navigational tabs and pills to create tabbable panes of local content.

If you're building our JavaScript from source, it [requires `util.js`]({{< docsref "/getting-started/javascript#util" >}}).

Dynamic tabbed interfaces, as described in the [WAI ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers).

Note that dynamic tabbed interfaces should not contain dropdown menus, as this causes both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies.

      Home

      Profile

      Contact

Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause she's got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. 'Cause I, I'm capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

```html
<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">...</div>
</div>
```

To help fit your needs, this works with `<ul>`-based markup, as shown above, or with any arbitrary "roll your own" markup. Note that if you're using `<nav>`, you shouldn't add `role="tablist"` directly to it, as this would override the element's native role as a navigation landmark. Instead, switch to an alternative element (in the example below, a simple `<div>`) and wrap the `<nav>` around it.

      Home
      Profile
      Contact

Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause she's got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. 'Cause I, I'm capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

```html
<nav>
  <div class="nav nav-tabs" id="nav-tab" role="tablist">
    <a class="nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
    <a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</a>
    <a class="nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</a>
  </div>
</nav>
<div class="tab-content" id="nav-tabContent">
  <div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">...</div>
  <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">...</div>
  <div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">...</div>
</div>
```

The tabs plugin also works with pills.

      Home

      Profile

      Contact

Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause she's got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. 'Cause I, I'm capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

```html
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="pills-tabContent">
  <div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab">...</div>
  <div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">...</div>
  <div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">...</div>
</div>
```

And with vertical pills.

        Home
        Profile
        Messages
        Settings

Placeholder content for the tab panel. This one relates to the home tab. Saw you downtown singing the Blues. Watch you circle the drain. Why don't you let me stop by? Heavy is the head that wears the crown. Yes, we make angels cry, raining down on earth from up above. Wanna see the show in 3D, a movie. Do you ever feel, feel so paper thin. It's a yes or no, no maybe.

Placeholder content for the tab panel. This one relates to the profile tab. Takes you miles high, so high, 'cause she's got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. 'Cause I, I'm capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

Placeholder content for the tab panel. This one relates to the messages tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

Placeholder content for the tab panel. This one relates to the settings tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

```html
<div class="row">
  <div class="col-3">
    <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
      <a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>
      <a class="nav-link" id="v-pills-profile-tab" data-toggle="pill" href="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
      <a class="nav-link" id="v-pills-messages-tab" data-toggle="pill" href="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>
      <a class="nav-link" id="v-pills-settings-tab" data-toggle="pill" href="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
    </div>
  </div>
  <div class="col-9">
    <div class="tab-content" id="v-pills-tabContent">
      <div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">...</div>
      <div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">...</div>
      <div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab">...</div>
      <div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab">...</div>
    </div>
  </div>
</div>
```

### Using data attributes

You can activate a tab or pill navigation without writing any JavaScript by simply specifying `data-toggle="tab"` or `data-toggle="pill"` on an element. Use these data attributes on `.nav-tabs` or `.nav-pills`.

```html
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
  </li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
  <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
  <div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
  <div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab">...</div>
  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab">...</div>
</div>
```

### Via JavaScript

Enable tabbable tabs via JavaScript (each tab needs to be activated individually):

```js
$('#myTab a').on('click', function (event) {
  event.preventDefault()
  $(this).tab('show')
})
```

You can activate individual tabs in several ways:

```js
$('#myTab a[href="#profile"]').tab('show') // Select tab by name
$('#myTab li:first-child a').tab('show') // Select first tab
$('#myTab li:last-child a').tab('show') // Select last tab
$('#myTab li:nth-child(3) a').tab('show') // Select third tab
```

### Fade effect

To make tabs fade in, add `.fade` to each `.tab-pane`. The first tab pane must also have `.show` to make the initial content visible.

```html
<div class="tab-content">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
  <div class="tab-pane fade" id="messages" role="tabpanel" aria-labelledby="messages-tab">...</div>
  <div class="tab-pane fade" id="settings" role="tabpanel" aria-labelledby="settings-tab">...</div>
</div>
```

### Methods

{{< callout danger >}}
{{< partial "callout-danger-async-methods.md" >}}
{{< /callout >}}

#### $().tab

Activates a tab element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.

```html
<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
  </li>
</ul>

<div class="tab-content">
  <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
  <div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
  <div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab">...</div>
  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab">...</div>
</div>

<script>
  $(function () {
    $('#myTab li:last-child a').tab('show')
  })
</script>
```

#### .tab('show')

Selects the given tab and shows its associated pane. Any other tab that was previously selected becomes unselected and its associated pane is hidden. **Returns to the caller before the tab pane has actually been shown** (i.e. before the `shown.bs.tab` event occurs).

```js
$('#someTab').tab('show')
```

#### .tab('dispose')

Destroys an element's tab.

### Events

When showing a new tab, the events fire in the following order:

1. `hide.bs.tab` (on the current active tab)
2. `show.bs.tab` (on the to-be-shown tab)
3. `hidden.bs.tab` (on the previous active tab, the same one as for the `hide.bs.tab` event)
4. `shown.bs.tab` (on the newly-active just-shown tab, the same one as for the `show.bs.tab` event)

If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.

      Event Type
      Description

      show.bs.tab
      This event fires on tab show, but before the new tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.

      shown.bs.tab
      This event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.

      hide.bs.tab
      This event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use event.target and event.relatedTarget to target the current active tab and the new soon-to-be-active tab, respectively.

      hidden.bs.tab
      This event fires after a new tab is shown (and thus the previous active tab is hidden). Use event.target and event.relatedTarget to target the previous active tab and the new active tab, respectively.

```js
$('a[data-toggle="tab"]').on('shown.bs.tab', function (event) {
  event.target // newly activated tab
  event.relatedTarget // previous active tab
})
```


text:
require File.expand_path('test_helper', File.dirname(__FILE__))

class Post
  extend ActiveModel::Naming
end

class Tag
  extend ActiveModel::Naming
end

class TagsController < InheritedResources::Base
  belongs_to :post, :shallow => true, :finder => :find_by_slug
end

class BelongsToWithShallowTest < ActionController::TestCase
  tests TagsController

  def setup
    Post.expects(:find_by_slug).with('thirty_seven').returns(mock_post)
    mock_post.expects(:tags).returns(Tag)

    @controller.stubs(:resource_url).returns('/')
    @controller.stubs(:collection_url).returns('/')
  end

  def test_expose_all_tags_as_instance_variable_on_index
    Tag.expects(:scoped).returns([mock_tag])
    get :index, request_params(:post_id => 'thirty_seven')
    assert_equal mock_post, assigns(:post)
    assert_equal [mock_tag], assigns(:tags)
  end

  def test_expose_a_new_tag_on_new
    Tag.expects(:build).returns(mock_tag)
    get :new, request_params(:post_id => 'thirty_seven')
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  def test_expose_a_newly_create_tag_on_create
    Tag.expects(:build).with({'these' => 'params'}).returns(mock_tag(:save => true))
    post :create, request_params(:post_id => 'thirty_seven', :tag => {:these => 'params'})
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  def test_expose_the_requested_tag_on_show
    should_find_parents
    get :show, request_params(:id => '42')
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  def test_expose_the_requested_tag_on_edit
    should_find_parents
    get :edit, request_params(:id => '42')
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  def test_update_the_requested_object_on_update
    should_find_parents
    mock_tag.expects(:update_attributes).with({'these' => 'params'}).returns(true)
    put :update, request_params(:id => '42', :tag => {:these => 'params'})
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  def test_the_requested_tag_is_destroyed_on_destroy
    should_find_parents
    mock_tag.expects(:destroy)
    delete :destroy, request_params(:id => '42', :post_id => '37')
    assert_equal mock_post, assigns(:post)
    assert_equal mock_tag, assigns(:tag)
  end

  protected
    def should_find_parents
      mock_tag.expects(:post).returns(mock_post)
      mock_post.expects(:to_param).returns('thirty_seven')
      Tag.expects(:find).with('42').twice.returns(mock_tag)
    end

    def mock_post(stubs={})
      @mock_post ||= mock(stubs)
    end

    def mock_tag(stubs={})
      @mock_tag ||= mock(stubs)
    end

end


text:
using System;

namespace Stranne.VasttrafikNET.Attributes
{
    internal class ParameterAttribute : Attribute
    {
        internal readonly string ParameterName;
        internal readonly object DefaultValue;
        internal readonly bool Required;
        internal readonly bool QueryString;
        internal readonly int Order;

        public ParameterAttribute(string parameterName = null, object defaultValue = null, bool required = false, bool queryString = true, int order = 0)
        {
            ParameterName = parameterName;
            DefaultValue = defaultValue;
            Required = required;
            QueryString = queryString;
            Order = order;
        }
    }
}


text:
package collector

import (
	"fmt"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

type loadavgCollector struct {
	metric []prometheus.Gauge
}

func init() {
	Factories["loadavg"] = NewLoadavgCollector
}

// Take a prometheus registry and return a new Collector exposing load average.
func NewLoadavgCollector() (Collector, error) {
	return &loadavgCollector{
		metric: []prometheus.Gauge{
			prometheus.NewGauge(prometheus.GaugeOpts{
				Namespace: Namespace,
				Name:      "load1",
				Help:      "1m load average.",
			}),
			prometheus.NewGauge(prometheus.GaugeOpts{
				Namespace: Namespace,
				Name:      "load5",
				Help:      "5m load average.",
			}),
			prometheus.NewGauge(prometheus.GaugeOpts{
				Namespace: Namespace,
				Name:      "load15",
				Help:      "15m load average.",
			}),
		},
	}, nil
}

func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
	loads, err := getLoad()
	if err != nil {
		return fmt.Errorf("couldn't get load: %s", err)
	}
	for i, load := range loads {
		log.Debugf("Set load %d: %f", i, load)
		c.metric[i].Set(load)
		c.metric[i].Collect(ch)
	}
	return err
}


text:
export declare class TypeaheadUtils {
    static latinMap: any;
    static latinize(str: string): string;
    static escapeRegexp(queryToEscape: string): string;
    static tokenize(str: string, wordRegexDelimiters?: string, phraseRegexDelimiters?: string): Array<string>;
    static getValueFromObject(object: any, option: string): string;
}


text:
    This is Marc Climent, writer of this blog and developer.

    Follow him on Twitter or Google+.


text:
  pavlov.specify("expectThat Specifications", function() {
    return describe("", function() {
      var foo;
      foo = "bar";
      describe("When testing should equal", function() {
        expectThat(function() {
          return foo.should(equal("barz"));
        });
        expectThat(function() {
          return (foo + "test").should(equal("bartestz"));
        });
        return expectThat(function() {
          return 1..should(equal(2));
        });
      });
      describe("When testing shouldnt equal", function() {
        expectThat(function() {
          return foo.shouldnt(equal("bar"));
        });
        expectThat(function() {
          return (foo + "test").shouldnt(equal("bartest"));
        });
        return expectThat(function() {
          return 1..shouldnt(equal(1));
        });
      });
      describe("When testing to and be", function() {
        expectThat(function() {
          return foo.should(be(equal(to("barz"))));
        });
        expectThat(function() {
          return foo.shouldnt(be(equal(to("bar"))));
        });
        expectThat(function() {
          return (foo + "test").should(be(equal(to("bartestz"))));
        });
        return expectThat(function() {
          return (foo + "test").shouldnt(be(equal(to("bartest"))));
        });
      });
      describe("When testing for true", function() {
        expectThat(function() {
          return true.should(be(false));
        });
        expectThat(function() {
          return false.shouldnt(be(false));
        });
        expectThat(function() {
          return (foo === "bar").should(be(false));
        });
        expectThat(function() {
          return (foo === "baz").shouldnt(be(false));
        });
        expectThat(function() {
          return ("b" + "ar" === "bar").should(be(false));
        });
        expectThat(function() {
          return ("foo" === "baz").shouldnt(be(false));
        });
        expectThat(function() {
          return ("b" + "ar" === "bar").shouldnt(be(!false));
        });
        return expectThat(function() {
          return ("foo" === "baz").should(be(!false));
        });
      });
      describe("When testing for false", function() {
        expectThat(function() {
          return false.should(be(true));
        });
        expectThat(function() {
          return true.shouldnt(be(true));
        });
        expectThat(function() {
          return (foo === "baz").should(be(true));
        });
        expectThat(function() {
          return (foo === "bar").shouldnt(be(true));
        });
        expectThat(function() {
          return ("b" + "az" === "bar").should(be(true));
        });
        expectThat(function() {
          return ("b" + "az" === "baz").shouldnt(be(true));
        });
        expectThat(function() {
          return (foo === "bar").should(be(!true));
        });
        return expectThat(function() {
          return ("b" + "az" === "bar").shouldnt(be(!true));
        });
      });
      describe("When testing for null or undefined", function() {
        var testNull, testUndefined;
        testNull = null;
        testUndefined = void 0;
        expectThat(function() {
          return (testNull === null).should(be(false));
        });
        expectThat(function() {
          return (testNull === null).shouldnt(be(true));
        });
        expectThat(function() {
          return (testNull !== null).should(be(true));
        });
        expectThat(function() {
          return (testNull !== null).shouldnt(be(false));
        });
        expectThat(function() {
          return (testUndefined === void 0).should(be(false));
        });
        expectThat(function() {
          return (testUndefined === void 0).shouldnt(be(true));
        });
        expectThat(function() {
          return (testUndefined !== void 0).should(be(true));
        });
        expectThat(function() {
          return (testUndefined !== void 0).shouldnt(be(false));
        });
        expectThat(function() {
          return (null === null).should(be(false));
        });
        expectThat(function() {
          return ("" === null).should(be(true));
        });
        expectThat(function() {
          return (void 0 === void 0).should(be(false));
        });
        return expectThat(function() {
          return ("" === void 0).should(be(true));
        });
      });
      describe("When testing for throw", function() {
        expectThat(function() {
          return (function() {
            return 1 / 1;
          }).should(throwException);
        });
        return expectThat(function() {
          return (function() {
            throw "test";
          }).should(throwException("test exception"));
        });
      });
      describe("When testing for greater than", function() {
        expectThat(function() {
          return 10..should(be(greaterThan(11)));
        });
        expectThat(function() {
          return 10.1.should(be(greaterThan(10.2)));
        });
        expectThat(function() {
          return 11..shouldnt(be(greaterThan(10)));
        });
        return expectThat(function() {
          return 11..shouldnt(be(greaterThan(10)));
        });
      });
      describe("When testing for less than", function() {
        expectThat(function() {
          return 11..should(be(lessThan(11)));
        });
        expectThat(function() {
          return 10.3.should(be(lessThan(10.2)));
        });
        expectThat(function() {
          return 9.9.shouldnt(be(lessThan(10)));
        });
        return expectThat(function() {
          return 9..shouldnt(be(lessThan(10)));
        });
      });
      describe("When testing for greater than or equal to", function() {
        expectThat(function() {
          return 10..should(be(greaterThanOrEqual(to(10.1))));
        });
        expectThat(function() {
          return 10..should(be(greaterThanOrEqual(10.1)));
        });
        expectThat(function() {
          return 8..should(be(greaterThanOrEqual(to(9))));
        });
        expectThat(function() {
          return 9.9.should(be(greaterThanOrEqual(to(10))));
        });
        expectThat(function() {
          return 10.1.shouldnt(be(greaterThanOrEqual(to(10))));
        });
        return expectThat(function() {
          return 11..shouldnt(be(greaterThanOrEqual(to(10))));
        });
      });
      describe("When testing for less than or equal to", function() {
        expectThat(function() {
          return 11.1.should(be(lessThanOrEqual(to(11))));
        });
        expectThat(function() {
          return 10.3.should(be(lessThanOrEqual(to(10.2))));
        });
        expectThat(function() {
          return 9.9.shouldnt(be(lessThanOrEqual(to(10))));
        });
        expectThat(function() {
          return 10..shouldnt(be(lessThanOrEqual(to(10))));
        });
        return expectThat(function() {
          return 9..shouldnt(be(lessThanOrEqual(to(10))));
        });
      });
      describe("When testing strictly equal to", function() {
        var testFn, testFn2;
        testFn = function() {};
        testFn2 = function() {};
        expectThat(function() {
          return 1..should(be(strictlyEqual(to(1))));
        });
        expectThat(function() {
          return testFn.shouldnt(be(strictlyEqual(to(testFn))));
        });
        expectThat(function() {
          return testFn.should(be(strictlyEqual(to(testFn2))));
        });
        return expectThat(function() {
          return testFn2.shouldnt(be(strictlyEqual(to(testFn2))));
        });
      });
      return describe("When testing a provided explicit test name", function() {
        expectThat("Some Test Name", function() {
          return foo.should(equal("barz"));
        });
        return expectThat("Some OtherTest Name", function() {
          return foo.shouldnt(equal("bar"));
        });
      });
    });
  });


text:
.. _types-index:

=====
Types
=====

Waffle supports three types of feature flippers:

.. toctree::
   :maxdepth: 1

   flag
   switch
   sample


text: <!DOCTYPE html>


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace o365Sample.Models
{
    public class Office365Context
    {
        public List<Office365DiscoveryResource> Resources { get; set; }

        public List<OAuthTokenResponse> Tokens { get; set; }
    }
}