001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.client;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021
022/**
023 * Specifies how collection-valued query/form parameters are serialized to a single string.
024 *
025 * <p>
026 * When a parameter value is an {@link Iterable} or array, the elements are joined using the delimiter
027 * corresponding to the selected format.  {@link #REPEATED} instead emits one name=value pair per element.
028 *
029 * @since 9.2.1
030 */
031public enum CollectionFormat {
032
033   /** Elements joined with {@code ,} — e.g. {@code colors=red,green,blue}. */
034   COMMA(","),
035
036   /** Elements joined with {@code |} — e.g. {@code colors=red|green|blue}. */
037   PIPE("|"),
038
039   /** Elements joined with a space — e.g. {@code colors=red green blue}. */
040   SPACE(" "),
041
042   /** Elements joined with {@code \t} (tab) — e.g. {@code colors=red\tgreen\tblue}. */
043   TAB("\t"),
044
045   /** One parameter per element — e.g. {@code colors=red&colors=green&colors=blue}. Handled specially by the request builder. */
046   REPEATED(null);
047
048   private final String delimiter;
049
050   CollectionFormat(String delimiter) {
051      this.delimiter = delimiter;
052   }
053
054   /**
055    * Returns the delimiter string, or {@code null} for {@link #REPEATED}.
056    *
057    * @return The delimiter, possibly <jk>null</jk>.
058    */
059   public String getDelimiter() {
060      return delimiter;
061   }
062
063   /**
064    * Serializes the given values to a single string using this format's delimiter.
065    *
066    * <p>
067    * Only valid for non-{@link #REPEATED} formats.
068    *
069    * @param values The values to join. Must not be <jk>null</jk>.
070    * @return The joined string. Never <jk>null</jk>.
071    * @throws IllegalArgumentException If called on {@link #REPEATED}.
072    */
073   public String join(Iterable<?> values) {
074      req(delimiter != null, "join() is not supported for CollectionFormat.REPEATED");
075      var sb = new StringBuilder();
076      var first = true;
077      for (var v : values) {
078         if (!first)
079            sb.append(delimiter);
080         sb.append(v);
081         first = false;
082      }
083      return sb.toString();
084   }
085}