Java tutorial
/* * ConsoleLicenseGenerator.java from LicenseManager modified Monday, April 8, 2013 13:14:00 CDT (-0500). * * Copyright 2010-2013 the original author or authors. * * 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. */ package net.nicholaswilliams.java.licensing.licensor.interfaces.cli; import net.nicholaswilliams.java.licensing.License; import net.nicholaswilliams.java.licensing.LicensingCharsets; import net.nicholaswilliams.java.licensing.encryption.FilePrivateKeyDataProvider; import net.nicholaswilliams.java.licensing.encryption.PasswordProvider; import net.nicholaswilliams.java.licensing.encryption.PrivateKeyDataProvider; import net.nicholaswilliams.java.licensing.exception.AlgorithmNotSupportedException; import net.nicholaswilliams.java.licensing.exception.InappropriateKeyException; import net.nicholaswilliams.java.licensing.exception.InappropriateKeySpecificationException; import net.nicholaswilliams.java.licensing.exception.KeyNotFoundException; import net.nicholaswilliams.java.licensing.exception.ObjectSerializationException; import net.nicholaswilliams.java.licensing.licensor.LicenseCreator; import net.nicholaswilliams.java.licensing.licensor.LicenseCreatorProperties; import net.nicholaswilliams.java.licensing.licensor.interfaces.cli.spi.CliOptionsBuilder; import net.nicholaswilliams.java.licensing.licensor.interfaces.cli.spi.TextInterfaceDevice; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * A command-line tool for generating licenses. Usage is as follows:<br /> * <br /> * To view usage and help:<br /> * <code>ConsoleLicenseGenerator -help</code><br /> * <br /> * To specify just config properties and be prompted for license properties:<br /> * <code>ConsoleLicenseGenerator -config <file></code><br /> * <br /> * To specify just license properties and be prompted for config properties:<br /> * <code>ConsoleLicenseGenerator -license <file></code><br /> * <br /> * To specify all options via properties files:<br /> * <code>ConsoleLicenseGenerator -config <file> -license <file></code><br /> * <br /> * The ConsoleLicenseGenerator expects to be passed the path to two properties files, or one of them, or neither. * The "config" properties file contains information necessary to generate all licenses (key paths, passwords, etc.) * and generally will not need to change. The "license" properties file contains all of the information you need to * generate this particular license. See the Javadoc API documentation for information about the contents of these two * files.<br /> * <br /> * If you do not specify the "config" properties file, you will be prompted to provide the values that were expected in * that file. Likewise, if you do not specify the "license" properties file, you will be prompted to provide the values * that were expected in that file.<br /> * <br /> * <b>Required Config Properties File Properties</b><br /> * <code>net.nicholaswilliams.java.licensing.privateKeyFile=[The path to the file containing the encrypted private key; either this or net.nicholaswilliams.java.licensing.privateKeyClass must be specified.]<br /> * net.nicholaswilliams.java.licensing.privateKeyProvider=[The fully-qualified (canonical) name of the implementation of {@link net.nicholaswilliams.java.licensing.encryption.PrivateKeyDataProvider}; either this or net.nicholaswilliams.java.licensing.privateKeyFile must be specified.]<br /> * net.nicholaswilliams.java.licensing.privateKeyPassword=[The password for decrypting the private key; either this or net.nicholaswilliams.java.licensing.privateKeyPasswordClass must be specified.]<br /> * net.nicholaswilliams.java.licensing.privateKeyPasswordProvider=[The fully-qualified (canonical) name of the implementation of {@link net.nicholaswilliams.java.licensing.encryption.PasswordProvider} that provides the private key password; either this or net.nicholaswilliams.java.licensing.privateKeyPassword must be specified]</code><br /> * <br /> * <b>License Properties File Properties</b> (Specify only those that you wish to include in the license)<br /> * <code>net.nicholaswilliams.java.licensing.productKey=[The product key/serial number (String) for this license] * net.nicholaswilliams.java.licensing.holder=[The holder (String) for this license] * net.nicholaswilliams.java.licensing.issuer=[The issuer (String) for this license] * net.nicholaswilliams.java.licensing.subject=[The subject (String) for this license] * net.nicholaswilliams.java.licensing.issueDate=[The date this license was issued (defaults to the current date/time), format: YYYY-MM-DD hh:mm:ss in 24-hour time] * net.nicholaswilliams.java.licensing.goodAfterDate=[The date this license becomes active, format: YYYY-MM-DD hh:mm:ss in 24-hour time] * net.nicholaswilliams.java.licensing.goodBeforeDate=[The date this license expires, format: format: YYYY-MM-DD hh:mm:ss in 24-hour time] * net.nicholaswilliams.java.licensing.numberOfLicenses=[The seats/users/number of licenses this license is good for] * net.nicholaswilliams.java.licensing.features.MY_FEATURE=[Feature expiration date for "MY_FEATURE", format: YYYY-MM-DD hh:mm:ss in 24-hour time or "none"] * net.nicholaswilliams.java.licensing.features.ANOTHER_FEATURE=[Feature expiration date for "ANOTHER_FEATURE", format: YYYY-MM-DD hh:mm:ss in 24-hour time or "none"]</code><br /> * <br /> * You can specify any arbitrary number of features (and their expiration date) using multiple properties that start * with <code>net.nicholaswilliams.java.licensing.features</code>. The last part of the property key should be the * feature name. The value should either be "none" or the date the feature expires (YYYY-MM-DD hh:mm:ss in 24-hour * time).<br /> * <br /> * <b>NOTE:</b> The default behavior is to encrypt the resulting license with the password or password provider * specified in the config properties file. To override this and use a different password to encrypt the license, * add <code>net.nicholaswilliams.java.licensing.password=[encryption password]</code> to the license properties * file.<br /> * <br /> * <b>NOTE:</b> The default behavior is to print the resulting license, Base64-encoded, to standard out. Instead, you * can write the raw, binary license data to a specific file with the property * <code>net.nicholaswilliams.java.licensing.licenseFile=[file name]</code>. * * @author Nick Williams * @version 1.0.0 * @since 1.0.0 */ public class ConsoleLicenseGenerator { public static final String PROPERTY_PRIVATE_KEY_FILE = "net.nicholaswilliams.java.licensing.privateKeyFile"; public static final String PROPERTY_PRIVATE_KEY_PROVIDER = "net.nicholaswilliams.java.licensing.privateKeyProvider"; public static final String PROPERTY_PRIVATE_KEY_PASSWORD = "net.nicholaswilliams.java.licensing.privateKeyPassword"; public static final String PROPERTY_PRIVATE_KEY_PASSWORD_PROVIDER = "net.nicholaswilliams.java.licensing.privateKeyPasswordProvider"; public static final String PROPERTY_LICENSE_PRODUCT_KEY = "net.nicholaswilliams.java.licensing.productKey"; public static final String PROPERTY_LICENSE_HOLDER = "net.nicholaswilliams.java.licensing.holder"; public static final String PROPERTY_LICENSE_ISSUER = "net.nicholaswilliams.java.licensing.issuer"; public static final String PROPERTY_LICENSE_SUBJECT = "net.nicholaswilliams.java.licensing.subject"; public static final String PROPERTY_LICENSE_ISSUE_DATE = "net.nicholaswilliams.java.licensing.issueDate"; public static final String PROPERTY_LICENSE_GOOD_AFTER_DATE = "net.nicholaswilliams.java.licensing.goodAfterDate"; public static final String PROPERTY_LICENSE_GOOD_BEFORE_DATE = "net.nicholaswilliams.java.licensing.goodBeforeDate"; public static final String PROPERTY_LICENSE_NUM_LICENSES = "net.nicholaswilliams.java.licensing.numberOfLicenses"; public static final String PROPERTY_LICENSE_FEATURE_PREFIX = "net.nicholaswilliams.java.licensing.features."; public static final String PROPERTY_LICENSE_FILE = "net.nicholaswilliams.java.licensing.licenseFile"; public static final String PROPERTY_LICENSE_PASSWORD = "net.nicholaswilliams.java.licensing.password"; private static final int CLI_WIDTH = 105; private static final String USAGE = " ConsoleLicenseGenerator -help\r\n" + " ConsoleLicenseGenerator\r\n" + " ConsoleLicenseGenerator -config <file>\r\n" + " ConsoleLicenseGenerator -license <file>\r\n" + " ConsoleLicenseGenerator -config <file> -license <file>\r\n" + " \r\n" + " The ConsoleLicenseGenerator expects to be passed the path to two " + "properties files, or one of them, or neither. The \"config\" properties " + "file contains information necessary to generate all licenses (key paths, " + "passwords, etc.) and generally will not need to change. The \"license\" " + "properties file contains all of the information you need to generate this " + "particular license. See the Javadoc API documentation for information about " + "the contents of these two files.\r\n" + " \r\n" + " If you do not specify the \"config\" properties file, you will be prompted " + "to provide the values that were expected in that file. Likewise, if you do " + "not specify the \"license\" properties file, you will be prompted to " + "provide the values that were expected in that file."; private static final Option HELP = CliOptionsBuilder.get().withDescription("Display this help message") .hasArg(false).create("help"); private static final Option CONFIG = CliOptionsBuilder.get().withArgName("file") .withDescription("Specify the .properties file that configures this generator").hasArg(true) .isRequired(false).create("config"); private static final Option LICENSE = CliOptionsBuilder.get().withArgName("file") .withDescription("Specify the .properties file that contains the data for this license").hasArg(true) .isRequired(false).create("license"); private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private final TextInterfaceDevice device; private final CommandLineParser cliParser; protected CommandLine cli = null; protected ConsoleLicenseGenerator(TextInterfaceDevice textInterfaceDevice, CommandLineParser cliParser) { this.device = textInterfaceDevice; this.cliParser = cliParser; } @Override protected void finalize() throws Throwable { super.finalize(); this.device.printOutLn(); } protected void processCommandLineOptions(String[] arguments) { Options firstParseOptions = new Options(); firstParseOptions.addOption(HELP); Options options = new Options(); options.addOption(HELP).addOption(CONFIG).addOption(LICENSE); try { this.cli = this.cliParser.parse(firstParseOptions, arguments, true); if (this.cli.hasOption("help")) { HelpFormatter formatter = new HelpFormatter(); this.printHelp(formatter, options); this.device.exit(0); } else { this.cli = this.cliParser.parse(options, arguments); } } catch (ParseException e) { this.device.printErrLn(e.getLocalizedMessage()); HelpFormatter formatter = new HelpFormatter(); this.printHelp(formatter, options); this.device.exit(1); } } private void printHelp(HelpFormatter formatter, Options options) { OutputStreamWriter streamWriter = new OutputStreamWriter(this.device.out(), LicensingCharsets.UTF_8); PrintWriter printWriter = new PrintWriter(streamWriter); formatter.printHelp(printWriter, CLI_WIDTH, USAGE, null, options, 1, 3, null, false); printWriter.close(); try { streamWriter.close(); } catch (IOException e) { e.printStackTrace(this.device.err()); } } protected Properties readPropertiesFile(String fileName) throws Exception { File file = new File(fileName); if (!file.exists()) throw new FileNotFoundException("The file [" + fileName + "] does not exist."); if (!file.canRead()) throw new IOException("The file [" + fileName + "] is not readable."); InputStreamReader reader = null; FileInputStream stream = null; try { stream = new FileInputStream(file); reader = new InputStreamReader(stream, LicensingCharsets.UTF_8); Properties properties = new Properties(); properties.load(reader); return properties; } finally { if (reader != null) { try { reader.close(); } catch (Throwable ignore) { } } if (stream != null) { try { stream.close(); } catch (Throwable ignore) { } } } } protected String promptForString(String message) { String input = this.device.readLine(message); this.device.printOutLn(); return input != null && input.trim().length() > 0 ? input.trim() : null; } protected char[] promptForPassword(String message) { char[] input = this.device.readPassword(message); this.device.printOutLn(); return input != null && input.length > 0 ? input : null; } protected void initializeLicenseCreator() throws Exception { Properties properties = null; if (this.cli.hasOption("config")) { String value = this.cli.getOptionValue("config"); if (value != null && value.trim().length() > 0) properties = this.readPropertiesFile(value); } LicenseCreatorProperties.setPrivateKeyDataProvider(this.getPrivateKeyDataProvider(properties)); LicenseCreatorProperties.setPrivateKeyPasswordProvider(this.getPrivateKeyPasswordProvider(properties)); LicenseCreator.getInstance(); } private boolean promptToUsePrivateKeyProviderClass() { this.device.printOutLn("Would you like to..."); this.device.printOutLn(" (1) Read the private key from a file?"); this.device.printOutLn(" (2) Use a PrivateKeyDataProvider implementation from the classpath?"); String input = this.device.readLine("Your selection (default 1)? "); this.device.printOutLn(); return input != null && input.trim().equals("2"); } private PrivateKeyDataProvider getPrivateKeyDataProvider(Properties properties) throws FileNotFoundException { PrivateKeyDataProvider provider; if (properties == null) { if (!this.promptToUsePrivateKeyProviderClass()) { String fileName = this.promptForString("Please enter the name of the private key file to use: "); File file = null; while (file == null) { while (fileName == null) { fileName = this .promptForString("Invalid or non-existent file. Please enter the name of the " + "private key file to use: "); } file = new File(fileName); if (!file.exists() || !file.canRead()) { fileName = null; file = null; } } provider = new FilePrivateKeyDataProvider(file); } else { String className = this.promptForString("Please enter the fully-qualified class name for the " + "PrivateKeyDataProvider implementation: "); while (className == null) { className = this.promptForString("Please enter the fully-qualified class name for the " + "PrivateKeyDataProvider implementation: "); } provider = this.getObjectAsClass(className, PrivateKeyDataProvider.class); } } else { String fileName = properties.getProperty(ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_FILE); if (fileName != null && fileName.trim().length() > 0) { File file = new File(fileName); if (!file.exists() || !file.canRead()) throw new FileNotFoundException("The private key file [" + file.getAbsolutePath() + "] does not exist or cannot be read."); provider = new FilePrivateKeyDataProvider(file); } else { String className = properties.getProperty(ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PROVIDER); if (className != null && className.trim().length() > 0) { provider = this.getObjectAsClass(className, PrivateKeyDataProvider.class); } else { throw new RuntimeException("Neither [" + ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_FILE + "] nor [" + ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PROVIDER + "] properties specified."); } } } return provider; } private boolean promptToUsePasswordProviderClass() { this.device.printOutLn("Would you like to..."); this.device.printOutLn(" (1) Type the private key password in manually?"); this.device.printOutLn(" (2) Use a PasswordProvider implementation from the classpath?"); String input = this.device.readLine("Your selection (default 1)? "); this.device.printOutLn(); return input != null && input.trim().equals("2"); } private static final class PrivatePasswordProvider implements PasswordProvider { private final char[] password; PrivatePasswordProvider(char[] password) { this.password = password; } @Override public char[] getPassword() { return this.password; } } private PasswordProvider getPrivateKeyPasswordProvider(Properties properties) { PasswordProvider provider; if (properties == null) { if (!this.promptToUsePasswordProviderClass()) { char[] password = this.promptForPassword("Please type the password for the private key: "); while (password == null) password = this .promptForPassword("Invalid password. Please type the password for the private key: "); provider = new PrivatePasswordProvider(password); } else { String className = this.promptForString("Please enter the fully-qualified class name for the " + "PasswordProvider implementation: "); while (className == null) { className = this.promptForString("Please enter the fully-qualified class name for the " + "PasswordProvider implementation: "); } provider = this.getObjectAsClass(className, PasswordProvider.class); } } else { String password = properties.getProperty(ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PASSWORD); if (password != null && password.trim().length() > 0) { provider = new PrivatePasswordProvider(password.toCharArray()); } else { String className = properties .getProperty(ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PASSWORD_PROVIDER); if (className != null && className.trim().length() > 0) { provider = this.getObjectAsClass(className, PasswordProvider.class); } else { throw new RuntimeException("Neither [" + ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PASSWORD + "] nor [" + ConsoleLicenseGenerator.PROPERTY_PRIVATE_KEY_PASSWORD_PROVIDER + "] properties specified."); } } } return provider; } private <T> T getObjectAsClass(String className, Class<T> castClass) { try { Class<?> objectClass = Class.forName(className); return objectClass.asSubclass(castClass).newInstance(); } catch (ClassNotFoundException e) { throw new RuntimeException("The class [" + className + "] could not be located."); } catch (ClassCastException e) { throw new RuntimeException("The class [" + className + "] does not implement interface [" + castClass.getCanonicalName() + "]."); } catch (Exception e) { throw new RuntimeException("Unable to instantiate class [" + className + "].", e); } } protected void generateLicense() throws Exception { Properties properties = null; if (this.cli.hasOption("license")) { String value = this.cli.getOptionValue("license"); if (value != null && value.trim().length() > 0) properties = this.readPropertiesFile(value); } License.Builder builder = new License.Builder(); { String productKey = this.getLicenseProductKey(properties); if (productKey != null) builder.withProductKey(productKey); } { String holder = this.getLicenseHolder(properties); if (holder != null) builder.withHolder(holder); } { String issuer = this.getLicenseIssuer(properties); if (issuer != null) builder.withIssuer(issuer); } { String subject = this.getLicenseSubject(properties); if (subject != null) builder.withSubject(subject); } builder.withIssueDate(this.getLicenseIssueDate(properties)); builder.withGoodAfterDate(this.getLicenseGoodAfterDate(properties)); builder.withGoodBeforeDate(this.getLicenseGoodBeforeDate(properties)); builder.withNumberOfLicenses(this.getLicenseNumberOfLicenses(properties)); Map<String, Long> map = this.getLicenseFeatures(properties); for (Map.Entry<String, Long> entry : map.entrySet()) { String name = entry.getKey(); Long expiration = map.get(name); if (expiration == null || expiration <= 0L) builder.addFeature(name); else builder.addFeature(name, expiration); } char[] password = this.getLicensePassword(properties); byte[] licenseData; License license = builder.build(); if (password != null) licenseData = LicenseCreator.getInstance().signAndSerializeLicense(license, password); else licenseData = LicenseCreator.getInstance().signAndSerializeLicense(license); this.returnLicenseData(licenseData, properties); } private String getLicenseProductKey(Properties properties) { if (properties == null) return this.promptForString("Please enter a product key for this license (you can leave this blank): "); else return properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_PRODUCT_KEY); } private String getLicenseHolder(Properties properties) { if (properties == null) return this.promptForString("Please enter a holder for this license (you can leave this blank): "); else return properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_HOLDER); } private String getLicenseIssuer(Properties properties) { if (properties == null) return this.promptForString("Please enter an issuer for this license (you can leave this blank): "); else return properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_ISSUER); } private String getLicenseSubject(Properties properties) { if (properties == null) return this.promptForString("Please enter a subject for this license (you can leave this blank): "); else return properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_SUBJECT); } private long parseDate(String date) { if (date == null || date.trim().length() == 0) return 0L; try { return this.simpleDateFormat.parse(date).getTime(); } catch (java.text.ParseException e) { return 0L; } } private long getLicenseIssueDate(Properties properties) { if (properties == null) return this.parseDate(this.promptForString( "Please enter an issue date for this license " + "(YYYY-MM-DD hh:mm:ss or blank): ")); else return this.parseDate(properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_ISSUE_DATE)); } private long getLicenseGoodAfterDate(Properties properties) { if (properties == null) return this .parseDate(this.promptForString("Please enter an activation/good-after date for this license " + "(YYYY-MM-DD hh:mm:ss or blank): ")); else return this.parseDate(properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_GOOD_AFTER_DATE)); } private long getLicenseGoodBeforeDate(Properties properties) { if (properties == null) return this.parseDate(this.promptForString( "Please enter an expiration date for this license " + "(YYYY-MM-DD hh:mm:ss or blank): ")); else return this .parseDate(properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_GOOD_BEFORE_DATE)); } private int parseInt(String integer) { if (integer == null || integer.trim().length() == 0) return 0; try { return Integer.parseInt(integer); } catch (Exception e) { return 0; } } private int getLicenseNumberOfLicenses(Properties properties) { if (properties == null) return this.parseInt(this.promptForString( "Please enter a number of seats/licenses for this license " + "(you can leave this blank): ")); else return this.parseInt(properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_NUM_LICENSES)); } public Map<String, Long> getLicenseFeatures(Properties properties) { Map<String, Long> map = new HashMap<String, Long>(); if (properties == null) { String featureName = this .promptForString("Optionally enter the name/key of a feature you want to add to " + "this license (you can leave this blank): "); while (featureName != null) { long expiration = this .parseDate(this.promptForString("Optionally enter an expiration date for feature [" + featureName + "] (YYYY-MM-DD hh:mm:ss or blank): ")); map.put(featureName, expiration); featureName = this.promptForString( "Enter another feature to add to this license (you can leave " + "this blank): "); } } else { for (String key : properties.stringPropertyNames()) { if (key.startsWith(ConsoleLicenseGenerator.PROPERTY_LICENSE_FEATURE_PREFIX)) { String featureName = key.replace(ConsoleLicenseGenerator.PROPERTY_LICENSE_FEATURE_PREFIX, ""); long expiration = this.parseDate(properties.getProperty(key)); map.put(featureName, expiration); } } } return map; } private char[] getLicensePassword(Properties properties) { if (properties == null) { char[] password = this.device.promptForValidPassword(0, 32, "the license with (if left blank, will use " + "the private key password provider)"); this.device.printOutLn(); return password == null || password.length == 0 ? null : password; } else { String password = properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_PASSWORD); return password == null || password.trim().length() == 0 ? null : password.toCharArray(); } } private boolean promptToWriteLicenseToFile() { this.device.printOutLn("Would you like to..."); this.device.printOutLn(" (1) Output the Base64-encoded license data to the screen?"); this.device.printOutLn(" (2) Write the raw, binary license data to a file?"); String input = this.device.readLine("Your selection (default 1)? "); this.device.printOutLn(); return input != null && input.trim().equals("2"); } private void returnLicenseData(byte[] licenseData, Properties properties) throws Exception { if (properties == null) { if (this.promptToWriteLicenseToFile()) { String fileName = this .promptForString("Please enter the name of the file to save the license to: "); while (fileName == null) { fileName = this.promptForString( "Invalid file name. Please enter the name of the file to save " + "the license to: "); } File file = new File(fileName); FileUtils.writeByteArrayToFile(file, licenseData); } else { this.device.printOutLn("License Data:"); this.device.printOutLn(new String(Base64.encodeBase64(licenseData), LicensingCharsets.UTF_8)); } } else { String fileName = properties.getProperty(ConsoleLicenseGenerator.PROPERTY_LICENSE_FILE); if (fileName != null && fileName.trim().length() > 0) { File file = new File(fileName); FileUtils.writeByteArrayToFile(file, licenseData); } else { this.device.printOut(new String(Base64.encodeBase64(licenseData), LicensingCharsets.UTF_8)); } } } public void run(String[] arguments) { this.processCommandLineOptions(arguments); try { this.initializeLicenseCreator(); this.generateLicense(); } catch (KeyNotFoundException e) { this.device.printErrLn(e.getLocalizedMessage() + " Correct the error and try again."); this.device.exit(51); return; } catch (ObjectSerializationException e) { this.device.printErrLn(e.getLocalizedMessage() + " Correct the error and try again."); this.device.exit(52); return; } catch (AlgorithmNotSupportedException e) { this.device.printErrLn(e.getLocalizedMessage() + " Contact your system administrator for assistance."); this.device.exit(41); return; } catch (InappropriateKeyException e) { this.device.printErrLn(e.getLocalizedMessage() + " Contact your system administrator for assistance."); this.device.exit(42); return; } catch (InappropriateKeySpecificationException e) { this.device.printErrLn(e.getLocalizedMessage() + " Contact your system administrator for assistance."); this.device.exit(43); return; } catch (InterruptedException e) { // in theory, this error wouldn't actually get reached in this circumstance, // but we'll catch it just in case this.device.printErrLn("The system was interrupted while waiting for events to complete."); this.device.exit(44); return; } catch (IOException e) { this.device.printErrLn("An error occurred writing or reading files from the system. Analyze the error " + "below to determine what went wrong and fix it!"); this.device.printErrLn(e.toString()); e.printStackTrace(); this.device.exit(21); return; } catch (Throwable t) { this.device.printErrLn(t.toString()); t.printStackTrace(); this.device.exit(-1); return; } this.device.exit(0); } public static void main(String... arguments) { TextInterfaceDevice device = TextInterfaceDevice.CONSOLE; ConsoleUtilities.configureInterfaceDevice(device); new ConsoleLicenseGenerator(device, new GnuParser()).run(arguments); } }