UsageOptions.java #1

  • //
  • guest/
  • stuartrowe/
  • p4java/
  • r14.1/
  • src/
  • main/
  • java/
  • com/
  • perforce/
  • p4java/
  • option/
  • UsageOptions.java
  • View
  • Commits
  • Open Download .zip Download (14 KB)
/**
 * 
 */
package com.perforce.p4java.option;

import java.util.Properties;

import com.perforce.p4java.PropertyDefs;
import com.perforce.p4java.exception.NullPointerError;
import com.perforce.p4java.exception.P4JavaError;

/**
 * Global server usage options class.<p>
 * 
 * Intended to implement some of the options described in
 * the main Perforce p4 usage and p4 undoc documentation on
 * a per-IOptionsServer object basis, and also implements some of
 * the broader environment settings (such as the client name used
 * by the P4Java server implementation when no client has been
 * associated with the server).<p>
 * 
 * The UsageOptions object associated with a server is read and used
 * for a small number of usage values (currently programName, programVersion,
 * unsetUserName, and unsetClientName) each time a command is issued to the
 * corresponding Perforce server, so updates to the UsageOptions object
 * and / or any associated Properties object will be reflected
 * at the next command execution except where noted. Note that this means that
 * UsageOption objects shared between multiple servers are sensitive to such
 * changes, and that changes that occur when a server is processing command
 * requests may cause unexpected results.<p>
 * 
 * A UsageOption object is associated with a server instance when
 * the server is issued by the server factory; this can be the default
 * object or one passed-in to the server factory specifically for that
 * server.<p>
 * 
 * Note that the UsageOptions class should be used with some
 * care as the possible side effects of setting some of the
 * usage parameters to the wrong value can lead to unexpected or
 * odd behaviour.
 */

public class UsageOptions {
	
	/**
	 * The name of the system property used to determine the JVM's current
	 * working directory.
	 */
	public static final String WORKING_DIRECTORY_PROPNAME = "user.dir";
	
	/**
	 * Properties object used to get default field values from. Note that
	 * these properties are potentially accessed for each command, so any
	 * changes in the properties will be reflected the next time the options
	 * object is used.
	 */
	protected Properties props = null;
	
	/**
	 * If not null, will be used to identify the P4Java application's
	 * program name to the Perforce server.
	 */
	protected String programName = null;
	
	/**
	 * If not null, will be used to identify the P4Java application's
	 * program version to the Perforce server.
	 */
	protected String programVersion = null;
	
	/**
	 * If not null, this specifies the Perforce server's idea of each command's
	 * working directory for the associated server object. Corresponds to
	 * the p4 -d usage option.<p>
	 * 
	 * This affects all commands on the associated server from this point on,
	 * and the passed-in path should be both absolute and valid, otherwise
	 * strange errors may appear from the server. If workingDirectory is null,
	 * the Java VM's actual current working directory <b>at the time this object
	 * is constructed</b> is used instead (which is almost always a safe option unless
	 * you're using Perforce alt roots).<p>
	 * 
	 * Note: no checking is done at any time for correctness (or otherwise)
	 * of the workingDirectory option.
	 */
	protected String workingDirectory = null;
	
	/**
	 * If not null, specifies the host name used by the server's commands.
	 * Set to null by the default constructor. Corresponds to the p4 -H
	 * usage option. HostName is not live -- that is, unlike many other
	 * UsageOption fields, its value is only read once when the associated
	 * server is created; subsequent changes will not be reflected in the
	 * associated server.
	 */
	protected String hostName = null;
	
	/**
	 * If not null, use this field to tell the server which language to
	 * use in text messages it sends back to the client. Corresponds to
	 * the p4 -L option, with the same limitations. Set to null by
	 * the default constructor.
	 */
	protected String textLanguage = null;
	
	/**
	 * What will be sent to the Perforce server with each command as the user
	 * name if no user name has been explicitly set for servers associated with
	 * this UsageOption.
	 */
	protected String unsetUserName = null;
	
	/**
	 * If set, this will be used as the name of the client when no
	 * client has actually been explicitly set for the associated server(s).
	 */
	protected String unsetClientName = null;
	
	/**
	 * Default working directory from the JVM to fall back to if not working
	 * directory is set on the usage options
	 */
	protected String defaultWorkingDirectory = null;
	

	/**
	 * Default constructor. Sets props field then calls setFieldDefaults
	 * to set appropriate field default values; otherwise does nothing.
	 */
	public UsageOptions(Properties props) {
		if (props == null) {
			this.props = new Properties();
		} else {
			this.props = props;
		}
		setFieldDefaults(getProps());
	}

	/**
	 * Explicit value constructor. After setting any values explicitly,
	 * calls setFieldDefaults() to tidy up any still-null fields that shouldn't
	 * be null.
	 */
	public UsageOptions(Properties props, String programName, String programVersion,
			String workingDirectory, String hostName, String textLanguage,
			String unsetUserName, String noClientName) {
		if (props == null) {
			this.props = new Properties();
		} else {
			this.props = props;
		}
		this.programName = programName;
		this.programVersion = programVersion;
		this.workingDirectory = workingDirectory;
		this.hostName = hostName;
		this.textLanguage = textLanguage;
		this.unsetUserName = unsetUserName;
		this.unsetClientName = noClientName;
		setFieldDefaults(getProps());
	}
	
	/**
	 * Set any non-null default values when the object
	 * is constructed. Basically, this means running down the fields
	 * and if a field is null and it's not a field that should have a null
	 * default value, calling the corresponding getXXXXDefault method.<p>
	 * 
	 * Fields set here: workingDirectory.
	 */
	protected void setFieldDefaults(Properties props) {
		this.defaultWorkingDirectory = getWorkingDirectoryDefault(props);
	}
	
	/**
	 * Get a suitable default value for the programName field.
	 * This version tries to find a suitable value in the passed-in
	 * properties with the key PropertyDefs.PROG_NAME_KEY_SHORTFORM, then
	 * with the key PropertyDefs.PROG_NAME_KEY; if that comes up null,
	 * it uses the value of PropertyDefs.PROG_NAME_DEFAULT.
	 * 
	 * @return non-null default programName value.
	 */
	protected String getProgramNameDefault(Properties props) {
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.PROG_NAME_KEY_SHORTFORM,
				props.getProperty(PropertyDefs.PROG_NAME_KEY,
						PropertyDefs.PROG_NAME_DEFAULT));
	}
	
	/**
	 * Get a suitable default value for the programVersion field.
	 * This version tries to find a suitable value in the passed-in
	 * properties with the key PropertyDefs.PROG_VERSION_KEY_SHORTFORM, then
	 * with the key PropertyDefs.PROG_VERSION_KEY; if that comes up null,
	 * it uses the value of PropertyDefs.PROG_VERSION_DEFAULT.
	 * 
	 * @return non-null default programVersion value.
	 */
	protected String getProgramVersionDefault(Properties props) {
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.PROG_VERSION_KEY_SHORTFORM,
				props.getProperty(PropertyDefs.PROG_VERSION_KEY,
						PropertyDefs.PROG_VERSION_DEFAULT));
	}
	
	/**
	 * Get a suitable default value for the workingDirectory field. This
	 * is taken from the JVM's system properties using the WORKING_DIRECTORY_PROPNAME
	 * system properties key (which is normally user.dir).
	 * 
	 * @return non-null working directory.
	 */
	protected String getWorkingDirectoryDefault(Properties props) {
		String cwd = System.getProperty(WORKING_DIRECTORY_PROPNAME);
		if (cwd == null) {
			// Oh dear. This should never happen...
			throw new P4JavaError(
					"Unable to retrieve current working directory from JVM system properties");
		}
			
		return cwd;
	}
	
	/**
	 * Get a suitable default value for the unsetUserName field. This version
	 * returns the value of the property associated with the PropertyDefs.USER_UNSET_NAME_KEY
	 * if it exists, or PropertyDefs.USER_UNSET_NAME_DEFAULT if not.
	 *
	 * @return non-null default unsetUserName value.
	 */
	protected String getUnsetUserNameDefault(Properties props) {
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return this.props.getProperty(PropertyDefs.USER_UNSET_NAME_KEY,
				PropertyDefs.USER_UNSET_NAME_DEFAULT);
	}
	
	/**
	 * Get a suitable default value for the unsetClientName field. This version
	 * returns the value of the property associated with the PropertyDefs.CLIENT_UNSET_NAME_KEY
	 * if it exists, or PropertyDefs.CLIENT_UNSET_NAME_DEFAULT if not.
	 *
	 * @return non-null default unsetClientName value.
	 */
	protected String getUnsetClientNameDefault(Properties props) {
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return this.props.getProperty(PropertyDefs.CLIENT_UNSET_NAME_KEY,
				PropertyDefs.CLIENT_UNSET_NAME_DEFAULT);
	}

	/**
	 * Return the program name. The current program name is determined by
	 * first seeing if there's been one explicitly set in this options object;
	 * if so, it's returned, otherwise the associated properties are searched
	 * for a value with the key PropertyDefs.PROG_NAME_KEY_SHORTFORM, then
	 * with the key PropertyDefs.PROG_NAME_KEY; if that comes up null,
	 * it returns the value of PropertyDefs.PROG_NAME_DEFAULT.
	 */
	public String getProgramName() {
		if (this.programName != null) {
			return this.programName;
		}
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.PROG_NAME_KEY_SHORTFORM,
				props.getProperty(PropertyDefs.PROG_NAME_KEY,
						PropertyDefs.PROG_NAME_DEFAULT));
	}

	public UsageOptions setProgramName(String programName) {
		this.programName = programName;
		return this;
	}

	/**
	 * Return the program version. The current program version is determined by
	 * first seeing if there's been one explicitly set in this options object;
	 * if so, it's returned, otherwise the associated properties are searched
	 * for a value with the key PropertyDefs.PROG_VERSION_KEY_SHORTFORM, then
	 * with the key PropertyDefs.PROG_VERSION_KEY; if that comes up null,
	 * it returns the value of PropertyDefs.PROG_VERSION_DEFAULT.
	 */
	public String getProgramVersion() {
		if (this.programVersion != null) {
			return this.programVersion;
		}
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.PROG_VERSION_KEY_SHORTFORM,
				props.getProperty(PropertyDefs.PROG_VERSION_KEY,
						PropertyDefs.PROG_VERSION_DEFAULT));
	}

	public UsageOptions setProgramVersion(String programVersion) {
		this.programVersion = programVersion;
		return this;
	}

	/**
	 * Return the current value of the working directory; this can be dynamically
	 * set explicitly using the setter method or implicitly when the object is
	 * constructed using the JVM's working directory as reflected in the
	 * System properties.
	 */
	public String getWorkingDirectory() {
		return workingDirectory != null ? workingDirectory
				: defaultWorkingDirectory;
	}

	public UsageOptions setWorkingDirectory(String workingDirectory) {
		this.workingDirectory = workingDirectory;
		return this;
	}

	public String getHostName() {
		return hostName;
	}

	/**
	 * Set the host name. Calling this method has no effect at all after
	 * any associated server object is created.
	 */
	public UsageOptions setHostName(String hostName) {
		this.hostName = hostName;
		return this;
	}

	public String getTextLanguage() {
		return textLanguage;
	}

	public UsageOptions setTextLanguage(String textLanguage) {
		this.textLanguage = textLanguage;
		return this;
	}

	public Properties getProps() {
		return props;
	}

	public UsageOptions setProps(Properties props) {
		this.props = props;
		return this;
	}

	/**
	 * Return the unset client name. The current value is determined by
	 * first seeing if there's been one explicitly set in this options object;
	 * if so, it's returned; otherwise the associated properties are searched
	 * for a value with the key PropertyDefs.CLIENT_UNSET_NAME_KEY; if that comes
	 * up null, it returns the value of PropertyDefs.CLIENT_UNSET_NAME_DEFAULT.
	 */
	public String getUnsetClientName() {
		if (this.unsetClientName != null) {
			return this.unsetClientName;
		}
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.CLIENT_UNSET_NAME_KEY,
						PropertyDefs.CLIENT_UNSET_NAME_DEFAULT);
	}

	public UsageOptions setUnsetClientName(String unsetClientName) {
		this.unsetClientName = unsetClientName;
		return this;
	}

	/**
	 * Return the unset user name. The current value is determined by
	 * first seeing if there's been one explicitly set in this options object;
	 * if so, it's returned; otherwise the associated properties are searched
	 * for a value with the key PropertyDefs.USER_UNSET_NAME_KEY; if that comes
	 * up null, it returns the value of PropertyDefs.USER_UNSET_NAME_DEFAULT.
	 */
	public String getUnsetUserName() {
		if (this.unsetUserName != null) {
			return this.unsetUserName;
		}
		if (props == null) {
			throw new NullPointerError("Null properties in UsageOptions");
		}
		return props.getProperty(PropertyDefs.USER_UNSET_NAME_KEY,
						PropertyDefs.USER_UNSET_NAME_DEFAULT);
	}

	public UsageOptions setUnsetUserName(String unsetUserName) {
		this.unsetUserName = unsetUserName;
		return this;
	}
}
# Change User Description Committed
#1 19903 stuartrowe Branching

//guest/perforce_software/p4java/...

to //guest/stuartrowe/p4java/...
//guest/perforce_software/p4java/r14.1/src/main/java/com/perforce/p4java/option/UsageOptions.java
#1 12541 Matt Attaway Initial add of the 14.1 p4java source code