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; 018 019import java.util.*; 020import java.util.regex.*; 021 022/** 023 * A click-triggered action on an element: an icon button that calls a handler. 024 * 025 * <h2 class='section'>Example:</h2> 026 * <p class='bjava'> 027 * ModelAction.<jsm>of</jsm>(<js>"archive"</js>).icon(<js>"archive"</js>).label(<js>"Archive"</js>).handler(<js>"orders.archive"</js>); 028 * </p> 029 * 030 * @since 10.0.0 031 */ 032@SuppressWarnings({ 033 "java:S1192", // Contract key names repeat as inline literals by design. 034 "java:S1845" // Instance field id and the ID pattern constant are distinct, conventionally named members. 035}) 036public final class ModelAction { 037 038 private static final Pattern ID = Pattern.compile("^[A-Za-z0-9_.-]{1,128}$"); 039 040 private final String id; 041 private String icon; 042 private String label; 043 private String tooltip; 044 private String tone; 045 private HandlerRef handler; 046 private Map<String,Object> payload; 047 048 private ModelAction(String id) { 049 if (id == null || ! ID.matcher(id).matches()) 050 throw new IllegalArgumentException("Action id '" + id + "' must match " + ID.pattern()); 051 this.id = id; 052 } 053 054 /** 055 * Starts an action. 056 * 057 * @param id The action id, unique per element. 058 * @return A new action. 059 * @throws IllegalArgumentException If the id is malformed. 060 */ 061 public static ModelAction of(String id) { 062 return new ModelAction(id); 063 } 064 065 /** 066 * Returns the action id. 067 * 068 * @return The id. 069 */ 070 public String id() { 071 return id; 072 } 073 074 /** 075 * Sets the icon (a sprite name). 076 * 077 * @param v The icon. 078 * @return This object. 079 */ 080 public ModelAction icon(String v) { 081 icon = v; 082 return this; 083 } 084 085 /** 086 * Sets the visible label. 087 * 088 * @param v The label. 089 * @return This object. 090 */ 091 public ModelAction label(String v) { 092 label = v; 093 return this; 094 } 095 096 /** 097 * Sets the tooltip. 098 * 099 * @param v The tooltip. 100 * @return This object. 101 */ 102 public ModelAction tooltip(String v) { 103 tooltip = v; 104 return this; 105 } 106 107 /** 108 * Sets the tone. 109 * 110 * @param v The tone. 111 * @return This object. 112 */ 113 public ModelAction tone(String v) { 114 tone = v; 115 return this; 116 } 117 118 /** 119 * Sets the handler by name. 120 * 121 * @param name A registered handler name or a listed built-in ({@code juneau.refresh}). 122 * @return This object. 123 * @throws IllegalArgumentException If the name is malformed. 124 */ 125 public ModelAction handler(String name) { 126 return handler(HandlerRef.named(name)); 127 } 128 129 /** 130 * Sets the handler. 131 * 132 * @param ref The handler reference. 133 * @return This object. 134 */ 135 public ModelAction handler(HandlerRef ref) { 136 handler = Objects.requireNonNull(ref, "handler"); 137 return this; 138 } 139 140 /** 141 * Sets the payload merged into the event payload. 142 * 143 * @param v The payload. 144 * @return This object. 145 */ 146 public ModelAction payload(Map<String,Object> v) { 147 payload = v == null ? null : new LinkedHashMap<>(v); 148 return this; 149 } 150 151 /** 152 * Returns the handler. 153 * 154 * @return The handler, or <jk>null</jk> if not yet set. 155 */ 156 HandlerRef handlerRef() { 157 return handler; 158 } 159 160 /** 161 * Serializes to the contract shape. 162 * 163 * @return The map, with {@code "type":"handler"}. 164 * @throws IllegalStateException If no handler was set. 165 */ 166 public Map<String,Object> toMap() { 167 if (handler == null) 168 throw new IllegalStateException("Action '" + id + "' has no handler."); 169 var m = new LinkedHashMap<String,Object>(); 170 m.put("type", "handler"); 171 m.put("id", id); 172 if (icon != null) 173 m.put("icon", icon); 174 if (label != null) 175 m.put("label", label); 176 if (tooltip != null) 177 m.put("tooltip", tooltip); 178 if (tone != null) 179 m.put("tone", tone); 180 m.put("handler", handler.toJson()); 181 if (payload != null) 182 m.put("payload", payload); 183 return m; 184 } 185}