package org.ff4j.cli; /* * #%L * ff4j-cli * %% * Copyright (C) 2013 - 2016 FF4J * %% * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. * #L% */ import static org.ff4j.cli.ansi.AnsiTerminal.cyan; import static org.ff4j.cli.ansi.AnsiTerminal.white; import static org.ff4j.cli.ansi.AnsiTerminal.yellow; import static org.ff4j.cli.ansi.AnsiTerminal.green; import static org.ff4j.cli.ansi.AnsiTerminal.red; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.ff4j.FF4j; import org.ff4j.cli.ansi.AnsiForegroundColor; import org.ff4j.cli.ansi.AnsiTerminal; import org.ff4j.cli.ansi.AnsiTextAttribute; import org.ff4j.core.Feature; import org.ff4j.core.FeatureStore; import org.ff4j.property.Property; import org.ff4j.property.PropertyBigDecimal; import org.ff4j.property.PropertyBigInteger; import org.ff4j.property.PropertyBoolean; import org.ff4j.property.PropertyByte; import org.ff4j.property.PropertyDouble; import org.ff4j.property.PropertyFloat; import org.ff4j.property.PropertyInt; import org.ff4j.property.PropertyLogLevel; import org.ff4j.property.PropertyLong; import org.ff4j.property.PropertyShort; import org.ff4j.property.PropertyString; import org.ff4j.property.store.PropertyStore; import org.ff4j.utils.Util; /** * Render all component for the FF4J commands. * * @author @clunven */ public class FF4jCliDisplay { /** Mapping from simple 'String' <=> 'org.ff4j.property.PropertyString'. */ private static Map < String , String > uxTypes = new HashMap< String , String>(); /** * Initialized Primitive to work with Properties. */ static { uxTypes.put(Byte.class.getSimpleName(), PropertyByte.class.getName()); uxTypes.put(Short.class.getSimpleName(), PropertyShort.class.getName()); uxTypes.put(Integer.class.getSimpleName(), PropertyInt.class.getName()); uxTypes.put(Long.class.getSimpleName(), PropertyLong.class.getName()); uxTypes.put(Double.class.getSimpleName(), PropertyDouble.class.getName()); uxTypes.put(Boolean.class.getSimpleName(), PropertyBoolean.class.getName()); uxTypes.put(Float.class.getSimpleName(), PropertyFloat.class.getName()); uxTypes.put(BigInteger.class.getSimpleName(), PropertyBigInteger.class.getName()); uxTypes.put(BigDecimal.class.getSimpleName(), PropertyBigDecimal.class.getName()); uxTypes.put("LogLevel", PropertyLogLevel.class.getName()); uxTypes.put(String.class.getSimpleName(), PropertyString.class.getName()); } /** * Default constructor. */ private FF4jCliDisplay() { } /** * Start Banner. */ public static void displayBanner() { AnsiTerminal.foreGroundColor(AnsiForegroundColor.GREEN); System.out.println(" __ __ _ _ _ "); System.out.println(" / _|/ _| || | (_)"); System.out.println("| |_| |_| || |_| |"); System.out.println("| _| _|__ _| |"); System.out.println("|_| |_| |_|_/ |"); System.out.print(" |__/ "); System.out.println("\n"); } /** * Display prompt like "ff4j@DEV>". * * @param currentEnv * environment selected if exists */ public static void displayPrompt(String currentEnv) { System.out.println(); AnsiTerminal.foreGroundColor(AnsiForegroundColor.GREEN); System.out.print("ff4j"); if (null != currentEnv) { AnsiTerminal.foreGroundColor(AnsiForegroundColor.WHITE); System.out.print("@"); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print(currentEnv); AnsiTerminal.foreGroundColor(AnsiForegroundColor.WHITE); } System.out.print(">"); System.out.flush(); AnsiTerminal.foreGroundColor(AnsiForegroundColor.WHITE); } /** * Template for helps. * * @param opt * options * @param message * current messages */ private static void lineHelp(String opt, String message) { System.out.println(""); cyan(" " + StringUtils.rightPad(opt, 43)); white(message); } /** * Help when no environnement is selected. */ public static void displayHelpNotConnected() { System.out.print("\nUsage (you are not connected) :"); lineHelp("?, help", "Display this help"); lineHelp("ls,list", "List available environments"); lineHelp("connect <envName> [-u <user>] [-p <passwd>]", "Connect to target environments"); lineHelp("exit,quit", "Exit the program\n"); } /** * Help when an environnement is selected. */ public static void displayHelpConnected() { System.out.print("\nUsage (you are connected):"); lineHelp("?, help", "Display this help"); lineHelp("conf", "Display ff4j configuration for this env"); lineHelp("ls,list", "List all available elements"); lineHelp("features", "List available features"); lineHelp("properties", "List available properties"); lineHelp("enableAudit", "Enable audit capability for current"); lineHelp("disableAudit", "Disable audit capability for current"); lineHelp("enable -f <feature>", "Toggle ON feature"); lineHelp("disable -f <feature>", "Toggle OFF feature"); lineHelp("grant -r <role> -f <feature>", "Grant role on feature"); lineHelp("revoke -r <role> -f <feature>", "Revoke role on feature"); lineHelp("enableGroup -g <group>", "Toggle ON group"); lineHelp("disableGroup -g <group>", "Toggle OFF group"); lineHelp("addToGroup -f <feature> -g <group>", "Add feature to target group"); lineHelp("removeFromGroup -f <feature> -g <group>", "Remove feature to target group"); lineHelp("update -p <property> -v <value>", "Update Property value"); lineHelp("quit", "Disconnect from current env"); lineHelp("exit", "Exit the program"); System.out.println(""); } /** * Display a table of available environments. * * @param envs * environnements in config file */ public static void displayEnvironments(Map < String, FF4j> envs) { yellow("+--------------------+----------+------------+-------+----------+\n"); System.out.print("|"); cyan(" Environments "); yellow("|"); cyan(" Features "); yellow("|"); cyan(" Properties "); yellow("|"); cyan(" Audit "); yellow("|"); cyan(" Security "); yellow("|\n"); System.out.println("+--------------------+----------+------------+-------+----------+"); for(Map.Entry<String, FF4j> entries : envs.entrySet()) { FeatureStore fs = entries.getValue().getFeatureStore(); PropertyStore ps = entries.getValue().getPropertiesStore(); yellow("| "); green(StringUtils.rightPad(entries.getKey(), 18)); yellow("| "); String featureStore = "---"; if (fs != null) { featureStore = String.valueOf(fs.readAll().size()); } white(StringUtils.rightPad(featureStore, 8)); yellow("| "); String propertyStore = "---"; if (fs != null) { propertyStore = String.valueOf(ps.listPropertyNames().size()); } white(StringUtils.rightPad(propertyStore, 10)); yellow("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); if (entries.getValue().isEnableAudit()) { green(" ON "); } else { red(" OFF "); } AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); yellow("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); if (entries.getValue().getAuthorizationsManager() != null) { green(" ON "); } else { red(" OFF "); } AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); yellow("|\n"); } System.out.println("+--------------------+----------+------------+-------+----------+"); System.out.println(""); } /** * Configuration for a sample environnement. * * @param ff4j * ff4j dedicated to the environnement. */ public static void displayConf(FF4j ff4j) { lineHelp("Version", ff4j.getVersion()); lineHelp("Autocreate", String.valueOf(ff4j.isAutocreate())); lineHelp("Audit", String.valueOf(ff4j.isEnableAudit())); String authManager = "---"; if (ff4j.getAuthorizationsManager() != null) { authManager = ff4j.getAuthorizationsManager().getClass().getName(); } lineHelp("Authorization Manager", authManager); String featStore = "---"; if (ff4j.getFeatureStore() != null) { featStore = ff4j.getFeatureStore().getClass().getName(); } lineHelp("Feature Store", featStore); String propStore = "---"; if (ff4j.getPropertiesStore() != null) { propStore = ff4j.getPropertiesStore().getClass().getName(); } lineHelp("Property Store", propStore); String evtStore = "---"; if (ff4j.getEventRepository() != null) { evtStore = ff4j.getEventRepository().getClass().getName(); } lineHelp("Event Store", evtStore); } /** * Command line uptime */ public static void displayProperties(Map < String, Property<?> > properties) { if (properties == null || properties.isEmpty()) { System.out.println(" There are no properties in the store"); } yellow("+--------------------+--------------------+--------------------+--------------------------------+"); System.out.print("\n|"); cyan(" Property names "); yellow("|"); cyan(" Value "); yellow("|"); cyan(" Type "); yellow("|"); cyan(" FixedValues "); yellow("|"); System.out.println("\n+--------------------+--------------------+--------------------+--------------------------------+"); for (Property<?> prop : properties.values()) { yellow("| "); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.GREEN); System.out.print(StringUtils.rightPad(prop.getName(), 19)); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); yellow("| "); white(StringUtils.rightPad(prop.asString(), 19)); yellow("| "); String pType = prop.getType(); if (uxTypes.containsValue(prop.getType())) { pType = Util.getFirstKeyByValue(uxTypes, prop.getType()); } white(StringUtils.rightPad(pType, 19)); yellow("| "); String fixedValues = "---"; if (prop.getFixedValues() != null && !prop.getFixedValues().isEmpty()) { fixedValues = prop.getFixedValues().toString(); if (fixedValues.length() > 31) { fixedValues = fixedValues.substring(0, 28) + "..."; } } white(StringUtils.rightPad(fixedValues, 31)); yellow("|\n"); } System.out.println("+--------------------+--------------------+--------------------+--------------------------------+"); } /** * Command line uptime */ public static void displayFeatures(Map < String, Feature > features) { if (features == null || features.isEmpty()) { System.out.println(" There are no features in the store"); } AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.println("+--------------------+--------+---------------+--------------------------------+"); System.out.print("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.CYAN); System.out.print(" Feature names "); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.CYAN); System.out.print(" State "); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.CYAN); System.out.print(" Group "); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("|"); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.CYAN); System.out.print(" Roles "); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.println("|"); System.out.println("+--------------------+--------+---------------+--------------------------------+"); for (Feature feat : features.values()) { AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("| "); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.GREEN); System.out.print(StringUtils.rightPad(feat.getUid(), 19)); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("| "); if (feat.isEnable()) { AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.GREEN); System.out.print(StringUtils.rightPad("ON", 7)); } else { AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.RED); System.out.print(StringUtils.rightPad("OFF", 7)); } AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("| "); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.WHITE); String groupName = "---"; if (!StringUtils.isEmpty(feat.getGroup())) { groupName = feat.getGroup(); } System.out.print(StringUtils.rightPad(groupName, 14)); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.print("| "); AnsiTerminal.textAttribute(AnsiTextAttribute.BOLD); AnsiTerminal.foreGroundColor(AnsiForegroundColor.WHITE); String roles = feat.getPermissions().toString(); roles = roles.substring(1, roles.length()-1); if ("".equals(roles)) { roles = "---"; } System.out.print(StringUtils.rightPad(roles, 31)); AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.println("| "); } AnsiTerminal.textAttribute(AnsiTextAttribute.CLEAR); AnsiTerminal.foreGroundColor(AnsiForegroundColor.YELLOW); System.out.println("+--------------------+--------+---------------+--------------------------------+"); } }