package com.perforce.api; import java.io.*; import java.util.*; /* * Copyright (c) 2001, Perforce Software, All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * Representation of a source control environment. This information is * typically passed to a <code>P4Process</code> instance by the * <code>SourceControlObject</code> instances. It can also be set in the * {@link P4Process#getBase() base} P4Process instance. This will cause it * to be used as the default environment for all command execution. * <P> * Values for the environment can be easily loaded from a * {@link java.util.Properties Properties} file. This makes configuration of * the environment much simpler. * * @see java.util.Properties * @author <a href="mailto:david@markley.cc">David Markley</a> * @version $Date: 2003/12/02 $ $Revision: #1 $ */ public class Env { private boolean envp_valid = false; private String[] envp; private Hashtable environ; private Properties props; private String p4_exe; // Full path to the P4 executable. private String sep_path = null; private String sep_file = null; private long threshold = 10000; /** Default, no-argument constructor. */ public Env() { super(); environ = new Hashtable(); environ.put("P4USER","robot"); environ.put("P4CLIENT","robot-client"); environ.put("P4PORT","localhost:1666"); environ.put("P4PASSWD",""); environ.put("PATH", "C:\\Program Files\\Perforce"); environ.put("CLASSPATH", "/usr/share/java/p4.jar"); environ.put("SystemDrive","C:"); environ.put("SystemRoot","C:\\WINNT"); environ.put("PATHEXT",".COM;.EXE;.BAT;.CMD"); setFromProperties(new Properties(System.getProperties())); } /** * Constructs an environment from a properties file. * * @param propfile full path to a properties file. */ public Env(String propfile) throws PerforceException { this(); setFromProperties(propfile); } /** * Constructor that uses another environment as its basis. This is useful * for cloning environments and then changing a few attributes. * * @param base Environment to be copied into the new environment. */ public Env(Env base) { this(); this.environ = (Hashtable)base.environ.clone(); this.props = (Properties)base.props.clone(); this.p4_exe = base.getExecutable(); } /** * Constructor that uses a set of <code>Properties</code> to set up the * environment. * * @see #setFromProperties(Properties) * @param props Used to construct the environment. */ public Env(Properties props) { this(); setFromProperties(props); } /** * Allows the user to set any environment variable. If the variable name * starts with 'P4', the value can not be set to null. It will instead be * set to the empty string. For all other variable, supplying a null * value will remove that variable form the environment. * * @param name environment variable name * @param value environment variable value */ public void setenv(String name, String value) { if (null == name) return; synchronized(environ) { if (null == value) { if (name.startsWith("P4")) { environ.put(name,""); } else { environ.remove(name); } } else { environ.put(name,value); } } envp_valid = false; } /** * Returns the value for the named environment variable. * * @param name environment variable name */ public String getenv(String name) { synchronized(environ) { return (String)environ.get(name); } } /** * Returns the environment in a <code>String</code> array. */ public String[] getEnvp() { String var; if (! envp_valid) { synchronized(environ) { envp = new String[environ.size()]; Enumeration en = environ.keys(); int i = 0; while (en.hasMoreElements()) { var = (String)en.nextElement(); envp[i++] = var+"="+environ.get(var); } } envp_valid = true; } return envp; } /** * Checks the environment to see if it is valid. To check the validity of * the environment, the user information is accessed. This ensures that * the server can be contacted and that the password is set properly. * <p> * If the environment is valid, this method will return quietly. Otherwise, * it will throw a <code>PerforceException</code> with a message regarding * the failure. */ public void checkValidity() throws PerforceException { String[] msg = { "Connect to server failed; check $P4PORT", "Perforce password (P4PASSWD) invalid or unset.", "Can't create a new user - over license quota." }; int msgndx = -1, i, cnt = 0; P4Process p = null; String l; String[] cmd = { "p4", "user", "-o"}; try { p = new P4Process(this); p.exec(cmd); while (null != (l = p.readLine())) { cnt++; for (i = 0; i < msg.length; i++) { if (-1 != l.indexOf(msg[i])) msgndx = i; } } p.close(); } catch (IOException ex) { if (null != p) { try { p.close(); } catch (Exception ignex) { /* Ignored Exception */ } } } if (-1 != msgndx) throw new PerforceException(msg[msgndx]); if (0 == cnt) throw new PerforceException("No output from p4 user -o"); } /** * Returns a <code>Vector</code> containing the property value list, as split up * by the commas. This is used to get the values for a property in the * form of: * <p> * some.property.key=val1,val2,val3 * <p> * Will always return a <code>Vector</code>, even if it is empty. * * @param key the property key * @param defaultValue a default value */ public Vector getPropertyList(String key, String defaultValue) { return getPropertyList(key, defaultValue, ","); } /** * Returns a <code>Vector</code> containing the property value list, as split up * by the specified delimeter. This is used to get the values for a property in the * form of: * <p> * some.property.key=val1,val2,val3 * <p> * Will always return a <code>Vector</code>, even if it is empty. * * @param key the property key * @param defaultValue a default value * @param delimeter string that seperates the values */ public Vector getPropertyList(String key, String defaultValue, String delimeter) { Vector v = new Vector(); String val, tok; StringTokenizer st; val = getProperty(key, defaultValue); st = new StringTokenizer(val, delimeter); while (st.hasMoreTokens()) { v.addElement(st.nextToken()); } return v; } /** * Returns a new <code>Properties</code> instance that is set using the * environments properties as its default. */ public Properties getProperties() { return new Properties(props); } /** * Searches for the property with the specified key in this property list. * If the key is not found in this property list, the default property list, * and its defaults, recursively, are then checked. The method returns * the default value argument if the property is not found. * * @param key the property key * @param defaultValue a default value * @return the value in this property list with the specified key value * @see java.util.Properties */ public String getProperty(String key, String defaultValue) { if (null == props) return defaultValue; return props.getProperty(key, defaultValue); } /** * Searches for the property with the specified key in this property list. * If the key is not found in this property list, the default property list, * and its defaults, recursively, are then checked. The method returns null * if the property is not found. * * @param key the property key * @return the value in this property list with the specified key value * @see java.util.Properties */ public String getProperty(String key) { return getProperty(key, null); } /** * Calls the hashtable method put. Provided for parallelism with the * getProperty method. Enforces use of strings for property keys and values. * * @param key the key to be placed into this property list. * @param value the value corresponding to key. * @see java.util.Properties#setProperty(String,String) */ public String setProperty(String key, String value) { String val = (String)props.setProperty(key, value); if (! key.startsWith("p4.")) { return val; } if (key.equals("p4.user")) { setUser(value); } else if (key.equals("p4.client")) { setClient(value); } else if (key.equals("p4.port")) { setPort(value); } else if (key.equals("p4.password")) { setPassword(value); } else if (key.equals("p4.executable")) { setExecutable(value); } else if (key.equals("p4.sysdrive")) { setSystemDrive(value); } else if (key.equals("p4.sysroot")) { setSystemRoot(value); } else if (key.equals("p4.threshold")) { try { setServerTimeout(Integer.valueOf(value).intValue()); } catch (Exception ex) { /* Ignored Exception */ } } return val; } /** * Sets the environment using the specified properties file. * * @see #setFromProperties(Properties) * @param propfile Path to a properties file. */ public void setFromProperties(String propfile) throws PerforceException { Properties props = new Properties(System.getProperties()); if (null != propfile) { try { props.load(new BufferedInputStream(new FileInputStream(propfile))); System.setProperties(props); } catch (Exception e) { System.err.println("Unable to load properties."); e.printStackTrace(System.err); throw new PerforceException("Unable to load properties from "+ propfile); } } setFromProperties(props); } /** * Uses a set of <code>Properties</code> to set up the environment. The * properties that are used used by this method are: * * <table border="1"> * <thead><tr><th>Property</th><th>Value Set</th></tr></thead><tbody> * <tr><td>p4.user</td><td>P4USER</td></tr> * <tr><td>p4.client</td><td>P4CLIENT</td></tr> * <tr><td>p4.port</td><td>P4PORT</td></tr> * <tr><td>p4.password</td><td>P4PASSWORD</td></tr> * <tr><td>p4.executable</td><td>Executable</td></tr> * <tr><td>p4.sysdrive</td><td>SystemDrive</td></tr> * <tr><td>p4.sysroot</td><td>SystemRoot</td></tr> * <tr><td>p4.threshold</td><td>Server Timeout Threshold</td></tr> * </tbody></table> * * @param props Used to construct the environment. */ public void setFromProperties(Properties props) { this.props = props; sep_path = getProperty("path.separator",";"); sep_file = getProperty("file.separator","/"); setUser(getProperty("p4.user","robot")); setClient(getProperty("p4.client","robot-client")); setPort(getProperty("p4.port","localhost:1666")); setPassword(getProperty("p4.password","")); setExecutable(getProperty("p4.executable", "P4")); setSystemDrive(getProperty("p4.sysdrive", "C:")); setSystemRoot(getProperty("p4.sysroot", "C:\\WINNT")); try { setServerTimeout(Integer.valueOf(getProperty("p4.threshold", "10000")).intValue()); } catch (Exception ex) { /* Ignored Exception */ } String os = props.getProperty("os.name"); if (null == os) { return; } if (os.startsWith("Windows")) { String windir = props.getProperty("com.ms.windir"); if (null != windir) { appendPath(windir.substring(0,1)+"\\Program Files\\Perforce"); setSystemDrive(windir.substring(0,1)); setSystemRoot(windir); } } } /** * Sets the P4USER in the class information. * * @param user P4USER value. */ public void setUser(String user) { if (null == user) return; environ.put("P4USER", user); props.setProperty("p4.user", user); envp_valid = false; } /** Returns the P4USER. */ public String getUser() { return (String)environ.get("P4USER"); } /** * Sets the P4CLIENT in the class information. * * @param user P4CLIENT value. */ public void setClient(String client) { if (null == client) return; environ.put("P4CLIENT", client); props.setProperty("p4.client", client); envp_valid = false; } /** Returns the P4CLIENT. */ public String getClient() { return (String)environ.get("P4CLIENT"); } /** * Sets the P4PORT in the class information. * * @param user P4PORT value. */ public void setPort(String port) { if (null == port) return; environ.put("P4PORT", port); props.setProperty("p4.port", port); envp_valid = false; } /** Returns the P4PORT. */ public String getPort() { return (String)environ.get("P4PORT"); } /** * Sets the P4PASSWD in the class information. * * @param user P4PASSWD value. */ public void setPassword(String password) { if (null == password) return; environ.put("P4PASSWD", password); props.setProperty("p4.password", password); envp_valid = false; } /** Returns the P4PASSWORD. */ public String getPassword() { return (String)environ.get("P4PASSWD"); } /** * Sets the PATH in the class information. * * @param path PATH value. */ public void setPath(String path) { if (null == path) return; environ.put("PATH", path); props.setProperty("p4.path", path); envp_valid = false; } /** * Append the path element to the existing path. If the path element * given is already in the path, no change is made. * * @param path the path element to be appended. */ public void appendPath(String path) { String tok; if (null == path) return; String orig_path = (String)environ.get("PATH"); if (null == sep_path || null == orig_path) { setPath(path); return; } StringTokenizer st = new StringTokenizer(orig_path, sep_path); StringBuffer sb = new StringBuffer(); while (st.hasMoreTokens()) { tok = (String)st.nextToken(); if (tok.equals(path)) return; sb.append(tok); sb.append(sep_path); } sb.append(path); setPath(path); } /** Returns the PATH. */ public String getPath() { return (String)environ.get("PATH"); } /** * Sets the SystemDrive in the class information. This is only * meaningful under Windows. * * @param user SystemDrive value. */ public void setSystemDrive(String drive) { if (null == drive) return; environ.put("SystemDrive", drive); props.setProperty("p4.sysdrive", drive); envp_valid = false; } /** * Sets the SystemRoot in the class information. This is only * meaningful under Windows. * * @param user SystemRoot value. */ public void setSystemRoot(String root) { if (null == root) return; environ.put("SystemRoot", root); props.setProperty("p4.sysroot", root); envp_valid = false; } /** * Sets up the path to reach the p4 executable. The full path passed in must * contain the executable or at least end in the system's file separator * character. This gotten from the file.separator property. For example: * <pre> * p4.executable=/usr/bin/p4 # This will work * p4.executable=/usr/bin/ # This will work * <font color=Red>p4.executable=/usr/bin # This won't work</font> * </pre> * * @param exe Full path to the p4 executable. */ public void setExecutable(String exe) { int pos; if (null == exe) return; p4_exe = exe; if (null == sep_file) { sep_file = System.getProperties().getProperty("file.separator","\\"); } if (-1 == (pos = exe.lastIndexOf(sep_file))) return; if (null == sep_path) { sep_path = System.getProperties().getProperty("path.separator",";"); } appendPath(exe.substring(0,pos)); props.setProperty("p4.executable", p4_exe); envp_valid = false; } /** Returns the path to the executable. */ public String getExecutable() { return p4_exe; } /** Set the server timeout threshold. */ public void setServerTimeout(long threshold) { this.threshold = threshold; props.setProperty("p4.threshold", String.valueOf(threshold)); } /** Return the server timeout threshold. */ public long getServerTimeout() { return threshold; } public String toString() { String[] envp = getEnvp(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < envp.length; i++) { sb.append(envp[i]); sb.append("\n"); } return sb.toString(); } /** * Returns an XML representation of the environment. */ public String toXML() { StringBuffer sb = new StringBuffer("<env"); sb.append(" user=\""); sb.append(getUser()); sb.append("\" client=\""); sb.append(getClient()); sb.append("\" port=\""); sb.append(getPort()); sb.append("\" password=\""); sb.append(getPassword()); sb.append("\" sysdrive=\""); sb.append(environ.get("SystemDrive")); sb.append("\" sysroot=\""); sb.append(environ.get("SystemRoot")); sb.append("\" threshold=\""); sb.append(threshold); sb.append("\"><executable>"); sb.append(getExecutable()); sb.append("</executable><path>"); sb.append(getPath()); sb.append("</path></env>"); return sb.toString(); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 3960 | Greg Abbas | branch for edit | ||
//public/perforce/api/java/p4package/com/perforce/api/Env.java | |||||
#5 | 1826 | David Markley | Incorporating minor changes in support of upcoming p4jsp package. | ||
#4 | 1382 | David Markley | Publicly changed Env and FileEntry | ||
#3 | 1361 | David Markley | Added convenience methods to the Env class. | ||
#2 | 1149 | David Markley | Added more documentation, a few examples, a cleanUp method, and a server timeout threshold. | ||
#1 | 1043 | David Markley | Initial branch to public area. | ||
//guest/david_markley/p4package/com/perforce/api/Env.java | |||||
#2 | 1035 | David Markley | Changed the file type to provide for keyword expansion. | ||
#1 | 1034 | David Markley |
Added P4Package sources as subset of the P4WebPublisher project. Copyright (c) 2001, Perforce Software, All rights reserved. |