import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; /** * Command line argument parsing shared by all examples. * * Every example is started the same way: * * ./SomeExample.java --superadmin --password * ./SomeExample.java --admin --password * * where <server> is the url of the collaboration server, including the web * application path, for example https://unblu.example.com/app * * This class deliberately does not use any type of the generated client, so that it can * be shared by examples that are compiled against different versions of it. */ public class Util { public static final String SUPERADMIN = "--superadmin"; public static final String ADMIN = "--admin"; private static final String PASSWORD = "--password"; private final String serverUrl; private final String username; private final String password; private Util(String serverUrl, String username, String password) { this.serverUrl = serverUrl; this.username = username; this.password = password; } /** * Parses the arguments of an example expecting a super admin user. * * @param args the arguments of the main method * @param scriptName the file name of the example, used in the usage message */ public static Util parseSuperadminArgs(String[] args, String scriptName) { return parseArgs(args, scriptName, SUPERADMIN); } /** * Parses the arguments of an example expecting an account admin user. * * @param args the arguments of the main method * @param scriptName the file name of the example, used in the usage message */ public static Util parseAdminArgs(String[] args, String scriptName) { return parseArgs(args, scriptName, ADMIN); } private static Util parseArgs(String[] args, String scriptName, String userOption) { if (args.length != 5) { exitWithUsage(scriptName, userOption); } String serverUrl = args[0]; if (serverUrl.startsWith("--")) { exitWithUsage(scriptName, userOption); } String username = readOption(args, userOption, scriptName, userOption); String password = readOption(args, PASSWORD, scriptName, userOption); return new Util(removeTrailingSlash(serverUrl), username, password); } private static String readOption(String[] args, String option, String scriptName, String userOption) { for (int i = 1; i < args.length - 1; i++) { if (option.equals(args[i])) { return args[i + 1]; } } System.err.println("Missing option: " + option); exitWithUsage(scriptName, userOption); return null; } private static String removeTrailingSlash(String value) { if (value.endsWith("/")) { return value.substring(0, value.length() - 1); } return value; } private static void exitWithUsage(String scriptName, String userOption) { System.err.println("Usage: " + scriptName + " " + userOption + " " + PASSWORD + " "); System.err.println(); System.err.println(" url of the collaboration server, for example https://unblu.example.com/app"); System.exit(1); } /** * Applies the deserialization settings recommended for every consumer of the * generated client: * *
    *
  • {@code FAIL_ON_UNKNOWN_PROPERTIES = false} so that a property added to a * response after this client was generated is ignored instead of failing; *
  • {@code READ_UNKNOWN_ENUM_VALUES_AS_NULL = true} so that an enum value added * after this client was generated deserializes to {@code null} instead of * throwing. *
* * Both matter more than they look. The generated enums are closed: without the * second setting, an ordinary read fails outright as soon as the server returns a * value the client does not know, and the whole response is lost rather than the * single field. Adding an enum value is a routine, non-breaking change on the * server, so this is not a rare situation. * * Call it on the mapper of the client: * *
Util.applyRecommendedDeserialization(client.getJSON().getContext(null));
*/ public static void applyRecommendedDeserialization(ObjectMapper mapper) { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); } /** * A short random suffix, for names that have to be unique on the server. Timestamps * are not good enough: two calls in the same millisecond collide, and a run that * creates several entities of the same kind needs a fresh value for each one. */ public static String randomSuffix() { return java.util.UUID.randomUUID().toString().substring(0, 8); } public String getServerUrl() { return serverUrl; } public String getUsername() { return username; } public String getPassword() { return password; } }