All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.appclient.client.acc.AppclientCommandArguments Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.appclient.client.acc;

import com.sun.enterprise.util.LocalStringManager;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.logging.LogDomains;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Encapsulates handling of appclient script command arguments and options.
 * 

* This class processes a list of strings which are the ACC and client arguments passed on the appclient script. It * makes each ACC argument available explicitly by its own method ({@link #getTargetServer} for example). The arguments * to be passed to the app client itself are available using {@link #getAppArgs }. * * * @author tjquinn */ public class AppclientCommandArguments { private final static Logger logger = Logger.getLogger(AppclientCommandArguments.class.getName()); private final static String LINE_SEP = System.getProperty("line.separator"); private final static Logger accLogger = LogDomains.getLogger(AppclientCommandArguments.class, LogDomains.ACC_LOGGER); /* * names of appclient options. * * Note that the scripts themselves handle the appclient "-client" option so -client is not one of the arguments managed * by this class. */ private final static String TEXTAUTH = "textauth"; private final static String NOAPPINVOKE = "noappinvoke"; private final static String MAINCLASS = "mainclass"; private final static String NAME = "name"; private final static String XML = "xml"; private final static String CONFIGXML = "configxml"; private final static String USER = "user"; private final static String PASSWORD = "password"; private final static String PASSWORDFILE = "passwordfile"; private final static String TARGETSERVER = "targetserver"; private final static String USAGE = "usage"; private final static String HELP = "help"; final static String PASSWORD_FILE_PASSWORD_KEYWORD = "PASSWORD"; /* names of options that take a value */ private final static String[] valuedArgNames = new String[] { MAINCLASS, NAME, XML, CONFIGXML, USER, PASSWORD, PASSWORDFILE, TARGETSERVER }; /* names of options that take no value */ private final static String[] unvaluedArgNames = new String[] { TEXTAUTH, NOAPPINVOKE, USAGE, HELP }; private static LocalStringManager localStrings = new LocalStringManagerImpl(AppclientCommandArguments.class);; private Map> valuedArgs = initValuedArgs(); private Map unvaluedArgs = initUnvaluedArgs(); private List unrecognizedArgs = new ArrayList<>(); private char[] password; private boolean isPasswordOptionUsed = false; private String configPathToUse; /** * Initializes the list of valued arguments with nulls for all values. * * @return */ private Map> initValuedArgs() { Map> valuedArgs = new HashMap<>(); for (String valuedArgName : valuedArgNames) { valuedArgs.put(valuedArgName, new AtomicReference(null)); } return valuedArgs; } /** * Initializes the list of unvalued arguments with false for all values, indicating that none of the options has been * seen (yet). * * @return */ private Map initUnvaluedArgs() { Map unvaluedArgs = new HashMap<>(); for (String unvaluedArgName : unvaluedArgNames) { unvaluedArgs.put(unvaluedArgName, new AtomicBoolean(false)); } return unvaluedArgs; } /** * Creates and returns a new AppclientCommandArguments object from which the ACC argument settings and the arguments to * be passed to the app client can be retrieved. * * @param appclientCommandArgs appclient command arguments to use in populating the launch info object * @return */ public static AppclientCommandArguments newInstance(List appclientCommandArgs) throws UserError { AppclientCommandArguments result = new AppclientCommandArguments(); result.processAppclientArgs(appclientCommandArgs); return result; } private AppclientCommandArguments() { } public boolean isTextauth() { return unvaluedArgs.get(TEXTAUTH).get(); } public boolean isNoappinvoke() { return unvaluedArgs.get(NOAPPINVOKE).get(); } public boolean isUsage() { return unvaluedArgs.get(USAGE).get(); } public boolean isHelp() { return unvaluedArgs.get(HELP).get(); } public String getUser() { return valuedArgs.get(USER).get(); } public char[] getPassword() { return password; } public String getName() { return valuedArgs.get(NAME).get(); } public String getTargetServer() { return valuedArgs.get(TARGETSERVER).get(); } private String getXML() { return valuedArgs.get(XML).get(); } private String getConfigXML() { return valuedArgs.get(CONFIGXML).get(); } public String getConfigFilePath() { if (configPathToUse == null) { configPathToUse = chooseConfigFilePath(); } return configPathToUse; } private String chooseConfigFilePath() { boolean isConfig = logger.isLoggable(Level.CONFIG); String pathToUse = null; if ((pathToUse = getXML()) != null) { if (isConfig) { logger.log(Level.CONFIG, "Choosing app client container config from -xml option: {0}", pathToUse); } } else if ((pathToUse = getConfigXML()) != null) { if (isConfig) { logger.log(Level.CONFIG, "Choosing app client container config from -configxml option: {0}", pathToUse); } } return pathToUse; } public String getMainclass() { return valuedArgs.get(MAINCLASS).get(); } public List getAppArgs() { return unrecognizedArgs; } private void processAppclientArgs(final List commandArgs) throws UserError { boolean isConfig = logger.isLoggable(Level.CONFIG); StringBuilder sb = (isConfig ? new StringBuilder("Arguments from appclient command:") : null); for (int slot = 0; slot < commandArgs.size(); slot++) { String arg = commandArgs.get(slot); if (arg.charAt(0) == '-') { arg = arg.substring(1); if (valuedArgs.containsKey(arg)) { if (slot < commandArgs.size()) { String value = commandArgs.get(++slot); /* * The scripts might use " " to enclose argument values, so if that's the case strip the quotes off. */ if ((value.length() > 1) && (value.charAt(0) == '\"') && (value.charAt(value.length() - 1) == '\"')) { value = value.substring(1, value.length() - 1); } if (arg.equals(PASSWORD)) { password = value.toCharArray(); isPasswordOptionUsed = true; if (isConfig) { sb.append(LINE_SEP).append(" ").append(arg).append("=???"); } } else { if (isConfig) { sb.append(LINE_SEP).append(" ").append(arg).append("=").append(value); } } valuedArgs.get(arg).set(value); if (arg.equals(PASSWORDFILE)) { processPasswordFile(value); } } else { throw new IllegalArgumentException(arg + "=?"); } } else if (unvaluedArgs.containsKey(arg)) { unvaluedArgs.get(arg).set(Boolean.TRUE); if (isConfig) { sb.append(LINE_SEP).append(" ").append(arg); } } else { unrecognizedArgs.add(arg); } } else { unrecognizedArgs.add(arg); } } if (isConfig) { logger.config(sb.toString()); } validateOptions(); } private void processPasswordFile(final String passwordFilePath) throws UserError { try { File pwFile = Util.verifyFilePath(passwordFilePath); /* * The file path looks good - read the password from it. */ password = loadPasswordFromFile(pwFile); } catch (IOException e) { String msg = localStrings.getLocalString(getClass(), "appclient.errorReadingFromPasswordFile", "Error reading the password from the password file {0}", new Object[] { passwordFilePath }); throw new UserError(msg, e); } } private char[] loadPasswordFromFile(final File pwFile) throws IOException, UserError { InputStream inputStream = null; try { inputStream = new BufferedInputStream(new FileInputStream(pwFile)); // XXX Should change this so we don't store the pw in a String even temporarily (as in the Props object) Properties props = new Properties(); props.load(inputStream); if (props.containsKey(PASSWORD_FILE_PASSWORD_KEYWORD)) { return props.getProperty(PASSWORD_FILE_PASSWORD_KEYWORD).toCharArray(); } else { final String msg = localStrings.getLocalString(getClass(), "appclient.noPasswordInFile", "The file {0} specified by the -passwordfile option should contain a setting PASSWORD=client-password-to-use but does not", new Object[] { pwFile.getAbsolutePath() }); throw new UserError(msg); } } finally { if (inputStream != null) { inputStream.close(); } } } private void validateOptions() throws UserError { ensureAtMostOneOfNameAndMainClass(); warnAboutPasswordUsage(); } /** * Makes sure that at most one of the -name and -mainclass arguments appeared on the command line. * * @throws IllegalArgumentException if both appeared */ private void ensureAtMostOneOfNameAndMainClass() throws UserError { if ((getMainclass() != null) && (getName() != null)) { throw new UserError(localStrings.getLocalString(getClass(), "appclient.mainclassOrNameNotBoth", "Specify either -mainclass or -name but not both to identify the app client to be run")); } } /** * Logs a warning if the user specified the -password command line option, which is discouraged and deprecated. */ private void warnAboutPasswordUsage() { if (isPasswordOptionUsed) { logger.warning(accLogger.getResourceBundle().getString("appclient.password.deprecated")); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy