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.console.freemarker;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import java.util.*;
022
023import org.apache.juneau.commons.http.*;
024import org.apache.juneau.marshall.collections.*;
025
026/**
027 * The built-in {@code bands} decorator: shaded x ranges from a list, a same-origin {@code src}, a {@code data:} topic,
028 * or the gaps in the first series ({@link #gaps()}).  The areas ride a carrier series {@code juneau-bands-<n>}.
029 *
030 * <h5 class='section'>Example:</h5>
031 * <p class='bjava'>
032 *    Bands.<jsm>from</jsm>(<js>"/rest/outages"</js>).start(<js>"from"</js>).end(<js>"to"</js>).label(<js>"Outage"</js>);
033 *    Bands.<jsm>gaps</jsm>().label(<js>"No data"</js>);
034 * </p>
035 *
036 * @since 10.0.0
037 */
038public final class Bands implements Decorator {
039
040   private final JsonMap m = JsonMap.of("use", "bands");
041
042   private Bands() {}
043
044   /** @param path A same-origin path returning rows. @return A new decorator. */
045   public static Bands from(String path) {
046      if (! SafePathTemplate.isSameOriginPath(path))
047         throw iaex("Bands src must be a same-origin path; got '%s'.", path);
048      var x = new Bands();
049      x.m.put("src", path);
050      return x;
051   }
052
053   /** @param rows Inline rows {@code {start, end, label?}}. @return A new decorator. */
054   public static Bands values(List<? extends Map<String,?>> rows) {
055      var x = new Bands();
056      x.m.put("values", Markers.copyRows(rows));
057      return x;
058   }
059
060   /** @param dataTopic A {@code data:} topic. @return A new decorator. */
061   public static Bands source(String dataTopic) {
062      var x = new Bands();
063      x.m.put("source", Markers.dataTopicOf("Bands", dataTopic));
064      return x;
065   }
066
067   /** Shades the runs of empty buckets in the first series. @return A new decorator. */
068   public static Bands gaps() {
069      var x = new Bands();
070      x.m.put("auto", "gaps");
071      return x;
072   }
073
074   /** @param field The row field holding the range start. @return This object. */
075   public Bands start(String field) { m.put("start", field); return this; }
076
077   /** @param field The row field holding the range end. @return This object. */
078   public Bands end(String field) { m.put("end", field); return this; }
079
080   /** @param v The band label. @return This object. */
081   public Bands label(String v) { m.put("label", v); return this; }
082
083   /** @param buckets The shortest gap shaded by {@link #gaps()}, at least 1. @return This object. */
084   public Bands minGap(int buckets) {
085      if (buckets < 1)
086         throw iaex("Bands minGap '%s' must be at least 1.", buckets);
087      m.put("minGap", buckets);
088      return this;
089   }
090
091   /** @param topic A custom topic the card publishes a click on a band to. @return This object. */
092   public Bands onClick(String topic) { m.put("topic", topic); return this; }
093
094   @Override
095   public JsonMap toJson() { return new JsonMap(m); }
096}