Copy source files from trunk sdk keeping revision history
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2009 Parametric Technology Corporation (PTC) |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import java.net.Socket; |
| | | import java.security.*; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | |
| | | import javax.net.ssl.KeyManager; |
| | | import javax.net.ssl.KeyManagerFactory; |
| | | import javax.net.ssl.TrustManagerFactory; |
| | | import javax.net.ssl.X509KeyManager; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class is in charge of checking whether the certificates that are |
| | | * presented are trusted or not. This implementation tries to check also that |
| | | * the subject DN of the certificate corresponds to the host passed using the |
| | | * setHostName method. |
| | | *<p> |
| | | * The constructor tries to use a default TrustManager from the system and if it |
| | | * cannot be retrieved this class will only accept the certificates explicitly |
| | | * accepted by the user (and specified by calling acceptCertificate). |
| | | *<p> |
| | | * NOTE: this class is not aimed to be used when we have connections in |
| | | * parallel. |
| | | */ |
| | | final class ApplicationKeyManager implements X509KeyManager |
| | | { |
| | | static private final Logger LOG = Logger |
| | | .getLogger(ApplicationKeyManager.class.getName()); |
| | | |
| | | /** |
| | | * The default keyManager. |
| | | */ |
| | | private X509KeyManager keyManager = null; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The default constructor. |
| | | * |
| | | * @param keystore |
| | | * The keystore to use for this keymanager. |
| | | * @param password |
| | | * The keystore password to use for this keymanager. |
| | | */ |
| | | ApplicationKeyManager(final KeyStore keystore, final char[] password) |
| | | { |
| | | KeyManagerFactory kmf = null; |
| | | String userSpecifiedAlgo = System |
| | | .getProperty("org.opends.admin.keymanageralgo"); |
| | | String userSpecifiedProvider = System |
| | | .getProperty("org.opends.admin.keymanagerprovider"); |
| | | |
| | | // Handle IBM specific cases if the user did not specify a algorithm |
| | | // and/or provider. |
| | | final String vendor = System.getProperty("java.vendor"); |
| | | if (vendor.startsWith("IBM")) |
| | | { |
| | | if (userSpecifiedAlgo == null) |
| | | { |
| | | userSpecifiedAlgo = "IbmX509"; |
| | | } |
| | | if (userSpecifiedProvider == null) |
| | | { |
| | | userSpecifiedProvider = "IBMJSSE2"; |
| | | } |
| | | } |
| | | |
| | | // Have some fallbacks to choose the provider and algorith of the |
| | | // key manager. First see if the user wanted to use something |
| | | // specific, then try with the SunJSSE provider and SunX509 |
| | | // algorithm. Finally, fallback to the default algorithm of the JVM. |
| | | final String[] preferredProvider = { userSpecifiedProvider, "SunJSSE", |
| | | null, null }; |
| | | final String[] preferredAlgo = { userSpecifiedAlgo, "SunX509", "SunX509", |
| | | TrustManagerFactory.getDefaultAlgorithm() }; |
| | | for (int i = 0; i < preferredProvider.length && keyManager == null; i++) |
| | | { |
| | | final String provider = preferredProvider[i]; |
| | | final String algo = preferredAlgo[i]; |
| | | if (algo == null) |
| | | { |
| | | continue; |
| | | } |
| | | try |
| | | { |
| | | if (provider != null) |
| | | { |
| | | kmf = KeyManagerFactory.getInstance(algo, provider); |
| | | } |
| | | else |
| | | { |
| | | kmf = KeyManagerFactory.getInstance(algo); |
| | | } |
| | | kmf.init(keystore, password); |
| | | final KeyManager kms[] = kmf.getKeyManagers(); |
| | | /* |
| | | * Iterate over the returned keymanagers, look for an instance of |
| | | * X509KeyManager. If found, use that as our "default" key manager. |
| | | */ |
| | | for (final KeyManager km : kms) |
| | | { |
| | | if (kms[i] instanceof X509KeyManager) |
| | | { |
| | | keyManager = (X509KeyManager) km; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | catch (final NoSuchAlgorithmException e) |
| | | { |
| | | // Nothing to do. Maybe we should avoid this and be strict, but |
| | | // we are in a best effor mode. |
| | | LOG.log(Level.WARNING, "Error with the algorithm", e); |
| | | } |
| | | catch (final KeyStoreException e) |
| | | { |
| | | // Nothing to do. Maybe we should avoid this and be strict, but |
| | | // we are in a best effor mode.. |
| | | LOG.log(Level.WARNING, "Error with the keystore", e); |
| | | } |
| | | catch (final UnrecoverableKeyException e) |
| | | { |
| | | // Nothing to do. Maybe we should avoid this and be strict, but |
| | | // we are in a best effor mode. |
| | | LOG.log(Level.WARNING, "Error with the key", e); |
| | | } |
| | | catch (final NoSuchProviderException e) |
| | | { |
| | | // Nothing to do. Maybe we should avoid this and be strict, but |
| | | // we are in a best effor mode. |
| | | LOG.log(Level.WARNING, "Error with the provider", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Choose an alias to authenticate the client side of a secure socket given |
| | | * the public key type and the list of certificate issuer authorities |
| | | * recognized by the peer (if any). |
| | | * |
| | | * @param keyType |
| | | * the key algorithm type name(s), ordered with the most-preferred |
| | | * key type first. |
| | | * @param issuers |
| | | * the list of acceptable CA issuer subject names or null if it does |
| | | * not matter which issuers are used. |
| | | * @param socket |
| | | * the socket to be used for this connection. This parameter can be |
| | | * null, in which case this method will return the most generic alias |
| | | * to use. |
| | | * @return the alias name for the desired key, or null if there are no |
| | | * matches. |
| | | */ |
| | | public String chooseClientAlias(final String[] keyType, |
| | | final Principal[] issuers, final Socket socket) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.chooseClientAlias(keyType, issuers, socket); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Choose an alias to authenticate the client side of a secure socket given |
| | | * the public key type and the list of certificate issuer authorities |
| | | * recognized by the peer (if any). |
| | | * |
| | | * @param keyType |
| | | * the key algorithm type name(s), ordered with the most-preferred |
| | | * key type first. |
| | | * @param issuers |
| | | * the list of acceptable CA issuer subject names or null if it does |
| | | * not matter which issuers are used. |
| | | * @param socket |
| | | * the socket to be used for this connection. This parameter can be |
| | | * null, in which case this method will return the most generic alias |
| | | * to use. |
| | | * @return the alias name for the desired key, or null if there are no |
| | | * matches. |
| | | */ |
| | | public String chooseServerAlias(final String keyType, |
| | | final Principal[] issuers, final Socket socket) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.chooseServerAlias(keyType, issuers, socket); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the certificate chain associated with the given alias. |
| | | * |
| | | * @param alias |
| | | * the alias name |
| | | * @return the certificate chain (ordered with the user's certificate first |
| | | * and the root certificate authority last), or null if the alias |
| | | * can't be found. |
| | | */ |
| | | public X509Certificate[] getCertificateChain(final String alias) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.getCertificateChain(alias); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the matching aliases for authenticating the server side of a secure |
| | | * socket given the public key type and the list of certificate issuer |
| | | * authorities recognized by the peer (if any). |
| | | * |
| | | * @param keyType |
| | | * the key algorithm type name |
| | | * @param issuers |
| | | * the list of acceptable CA issuer subject names or null if it does |
| | | * not matter which issuers are used. |
| | | * @return an array of the matching alias names, or null if there were no |
| | | * matches. |
| | | */ |
| | | public String[] getClientAliases(final String keyType, |
| | | final Principal[] issuers) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.getClientAliases(keyType, issuers); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the key associated with the given alias. |
| | | * |
| | | * @param alias |
| | | * the alias name |
| | | * @return the requested key, or null if the alias can't be found. |
| | | */ |
| | | public PrivateKey getPrivateKey(final String alias) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.getPrivateKey(alias); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the matching aliases for authenticating the server side of a secure |
| | | * socket given the public key type and the list of certificate issuer |
| | | * authorities recognized by the peer (if any). |
| | | * |
| | | * @param keyType |
| | | * the key algorithm type name |
| | | * @param issuers |
| | | * the list of acceptable CA issuer subject names or null if it does |
| | | * not matter which issuers are used. |
| | | * @return an array of the matching alias names, or null if there were no |
| | | * matches. |
| | | */ |
| | | public String[] getServerAliases(final String keyType, |
| | | final Principal[] issuers) |
| | | { |
| | | if (keyManager != null) |
| | | { |
| | | return keyManager.getServerAliases(keyType, issuers); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.util.StaticUtils.toLowerCase; |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.LinkedList; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a generic argument that may be used in the argument list |
| | | * for an application. This is an abstract class that must be subclassed in |
| | | * order to provide specific functionality. |
| | | */ |
| | | abstract class Argument |
| | | { |
| | | // Indicates whether this argument should be hidden in the usage |
| | | // information. |
| | | private boolean isHidden; |
| | | |
| | | // Indicates whether this argument may be specified more than once for |
| | | // multiple values. |
| | | private boolean isMultiValued; |
| | | |
| | | // Indicates whether this argument was provided in the set of |
| | | // command-line |
| | | // arguments. |
| | | private boolean isPresent; |
| | | |
| | | // Indicates whether this argument is required to have a value. |
| | | private boolean isRequired; |
| | | |
| | | // Indicates whether this argument requires a value. |
| | | private boolean needsValue; |
| | | |
| | | // The single-character identifier for this argument. |
| | | private final Character shortIdentifier; |
| | | |
| | | // The unique ID of the description for this argument. |
| | | private final LocalizableMessage description; |
| | | |
| | | // The set of values for this argument. |
| | | private final LinkedList<String> values; |
| | | |
| | | // The default value for the argument if none other is provided. |
| | | private String defaultValue; |
| | | |
| | | // The long identifier for this argument. |
| | | private final String longIdentifier; |
| | | |
| | | // The generic name that will be used to refer to this argument. |
| | | private final String name; |
| | | |
| | | // The name of the property that can be used to set the default value. |
| | | private String propertyName; |
| | | |
| | | // The value placeholder for this argument, which will be used in |
| | | // usage |
| | | // information. |
| | | private LocalizableMessage valuePlaceholder; |
| | | |
| | | // Indicates whether this argument was provided in the set of |
| | | // properties |
| | | // found is a properties file. |
| | | private boolean isValueSetByProperty; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | protected Argument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final String defaultValue, |
| | | final String propertyName, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | this.name = name; |
| | | this.shortIdentifier = shortIdentifier; |
| | | this.longIdentifier = longIdentifier; |
| | | this.isRequired = isRequired; |
| | | this.isMultiValued = isMultiValued; |
| | | this.needsValue = needsValue; |
| | | this.valuePlaceholder = valuePlaceholder; |
| | | this.defaultValue = defaultValue; |
| | | this.propertyName = propertyName; |
| | | this.description = description; |
| | | this.isValueSetByProperty = false; |
| | | |
| | | if ((shortIdentifier == null) && (longIdentifier == null)) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_NO_IDENTIFIER.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (needsValue && (valuePlaceholder == null)) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_NO_VALUE_PLACEHOLDER.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | values = new LinkedList<String>(); |
| | | isPresent = false; |
| | | isHidden = false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a value to the set of values for this argument. This should only be |
| | | * called if the value is allowed by the <CODE>valueIsAcceptable</CODE> |
| | | * method. |
| | | * |
| | | * @param valueString |
| | | * The string representation of the value to add to this argument. |
| | | */ |
| | | public void addValue(final String valueString) |
| | | { |
| | | values.add(valueString); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the set of values assigned to this argument. |
| | | */ |
| | | public void clearValues() |
| | | { |
| | | values.clear(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the value of this argument as a <CODE>Boolean</CODE>. |
| | | * |
| | | * @return The value of this argument as a <CODE>Boolean</CODE>. |
| | | * @throws ArgumentException |
| | | * If this argument cannot be interpreted as a Boolean value. |
| | | */ |
| | | public boolean getBooleanValue() throws ArgumentException |
| | | { |
| | | if (values.isEmpty()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_NO_BOOLEAN_VALUE.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | final Iterator<String> iterator = values.iterator(); |
| | | final String valueString = toLowerCase(iterator.next()); |
| | | |
| | | boolean booleanValue; |
| | | if (valueString.equals("true") || valueString.equals("yes") |
| | | || valueString.equals("on") || valueString.equals("1")) |
| | | { |
| | | booleanValue = true; |
| | | } |
| | | else if (valueString.equals("false") || valueString.equals("no") |
| | | || valueString.equals("off") || valueString.equals("0")) |
| | | { |
| | | booleanValue = false; |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_CANNOT_DECODE_AS_BOOLEAN.get( |
| | | valueString, name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (iterator.hasNext()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_BOOLEAN_MULTIPLE_VALUES |
| | | .get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | | { |
| | | return booleanValue; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the default value that will be used for this argument if it is |
| | | * not specified on the command line and it is not set from a properties file. |
| | | * |
| | | * @return The default value that will be used for this argument if it is not |
| | | * specified on the command line and it is not set from a properties |
| | | * file, or <CODE>null</CODE> if there is no default value. |
| | | */ |
| | | public String getDefaultValue() |
| | | { |
| | | return defaultValue; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the human-readable description for this argument. |
| | | * |
| | | * @return The human-readable description for this argument. |
| | | */ |
| | | public LocalizableMessage getDescription() |
| | | { |
| | | return description != null ? description : LocalizableMessage.EMPTY; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the value of this argument as an integer. |
| | | * |
| | | * @return The value of this argument as an integer. |
| | | * @throws ArgumentException |
| | | * If there are multiple values, or the value cannot be parsed as an |
| | | * integer. |
| | | */ |
| | | public double getDoubleValue() throws ArgumentException |
| | | { |
| | | if (values.isEmpty()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_NO_INT_VALUE.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | final Iterator<String> iterator = values.iterator(); |
| | | final String valueString = iterator.next(); |
| | | |
| | | double intValue; |
| | | try |
| | | { |
| | | intValue = Double.parseDouble(valueString); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_CANNOT_DECODE_AS_INT.get( |
| | | valueString, name); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | |
| | | if (iterator.hasNext()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_INT_MULTIPLE_VALUES.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | | { |
| | | return intValue; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of values for this argument as a list of integers. |
| | | * |
| | | * @return A list of the integer representations of the values for this |
| | | * argument. |
| | | * @throws ArgumentException |
| | | * If any of the values cannot be parsed as an integer. |
| | | */ |
| | | public LinkedList<Double> getDoubleValues() throws ArgumentException |
| | | { |
| | | final LinkedList<Double> intList = new LinkedList<Double>(); |
| | | |
| | | final Iterator<String> iterator = values.iterator(); |
| | | while (iterator.hasNext()) |
| | | { |
| | | final String valueString = iterator.next(); |
| | | |
| | | try |
| | | { |
| | | intList.add(Double.valueOf(valueString)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_CANNOT_DECODE_AS_INT.get( |
| | | valueString, name); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | } |
| | | |
| | | return intList; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the value of this argument as an integer. |
| | | * |
| | | * @return The value of this argument as an integer. |
| | | * @throws ArgumentException |
| | | * If there are multiple values, or the value cannot be parsed as an |
| | | * integer. |
| | | */ |
| | | public int getIntValue() throws ArgumentException |
| | | { |
| | | if (values.isEmpty()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_NO_INT_VALUE.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | final Iterator<String> iterator = values.iterator(); |
| | | final String valueString = iterator.next(); |
| | | |
| | | int intValue; |
| | | try |
| | | { |
| | | intValue = Integer.parseInt(valueString); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_CANNOT_DECODE_AS_INT.get( |
| | | valueString, name); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | |
| | | if (iterator.hasNext()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_INT_MULTIPLE_VALUES.get(name); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | | { |
| | | return intValue; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of values for this argument as a list of integers. |
| | | * |
| | | * @return A list of the integer representations of the values for this |
| | | * argument. |
| | | * @throws ArgumentException |
| | | * If any of the values cannot be parsed as an integer. |
| | | */ |
| | | public LinkedList<Integer> getIntValues() throws ArgumentException |
| | | { |
| | | final LinkedList<Integer> intList = new LinkedList<Integer>(); |
| | | |
| | | final Iterator<String> iterator = values.iterator(); |
| | | while (iterator.hasNext()) |
| | | { |
| | | final String valueString = iterator.next(); |
| | | |
| | | try |
| | | { |
| | | intList.add(Integer.valueOf(valueString)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_ARG_CANNOT_DECODE_AS_INT.get( |
| | | valueString, name); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | } |
| | | |
| | | return intList; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the long (multi-character) identifier that may be used to specify |
| | | * the value of this argument. |
| | | * |
| | | * @return The long (multi-character) identifier that may be used to specify |
| | | * the value of this argument. |
| | | */ |
| | | public String getLongIdentifier() |
| | | { |
| | | return longIdentifier; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the generic name that will be used to refer to this argument. |
| | | * |
| | | * @return The generic name that will be used to refer to this argument. |
| | | */ |
| | | public String getName() |
| | | { |
| | | return name; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the name of a property in a properties file that may be used to |
| | | * set the default value for this argument if it is present. A value read from |
| | | * a properties file will override the default value returned from the |
| | | * <CODE>getDefaultValue</CODE>, but the properties file value will be |
| | | * overridden by a value supplied on the command line. |
| | | * |
| | | * @return The name of a property in a properties file that may be used to set |
| | | * the default value for this argument if it is present. |
| | | */ |
| | | public String getPropertyName() |
| | | { |
| | | return propertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the single-character identifier that may be used to specify the |
| | | * value of this argument. |
| | | * |
| | | * @return The single-character identifier that may be used to specify the |
| | | * value of this argument, or <CODE>null</CODE> if there is none. |
| | | */ |
| | | public Character getShortIdentifier() |
| | | { |
| | | return shortIdentifier; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the string vale for this argument. If it has multiple values, |
| | | * then the first will be returned. If it does not have any values, then the |
| | | * default value will be returned. |
| | | * |
| | | * @return The string value for this argument, or <CODE>null</CODE> if there |
| | | * are no values and no default value has been given. |
| | | */ |
| | | public String getValue() |
| | | { |
| | | if (values.isEmpty()) |
| | | { |
| | | return defaultValue; |
| | | } |
| | | |
| | | return values.getFirst(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the value placeholder that will be displayed for this argument in |
| | | * the generated usage information. |
| | | * |
| | | * @return The value placeholder that will be displayed for this argument in |
| | | * the generated usage information, or <CODE>null</CODE> if there is |
| | | * none. |
| | | */ |
| | | public LocalizableMessage getValuePlaceholder() |
| | | { |
| | | return valuePlaceholder; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of string values for this argument. |
| | | * |
| | | * @return The set of string values for this argument. |
| | | */ |
| | | public LinkedList<String> getValues() |
| | | { |
| | | return values; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument has at least one value. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument has at least one value, or |
| | | * <CODE>false</CODE> if it does not have any values. |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return (!values.isEmpty()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument should be hidden from the usage |
| | | * information. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument should be hidden from the usage |
| | | * information, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isHidden() |
| | | { |
| | | return isHidden; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument may be provided more than once on the |
| | | * command line to specify multiple values. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument may be provided more than once |
| | | * on the command line to specify multiple values, or |
| | | * <CODE>false</CODE> if it may have at most one value. |
| | | */ |
| | | public boolean isMultiValued() |
| | | { |
| | | return isMultiValued; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument is present in the parsed set of |
| | | * command-line arguments. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument is present in the parsed set of |
| | | * command-line arguments, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isPresent() |
| | | { |
| | | return isPresent; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument is required to have at least one value. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument is required to have at least one |
| | | * value, or <CODE>false</CODE> if it does not need to have a value. |
| | | */ |
| | | public boolean isRequired() |
| | | { |
| | | return isRequired; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this argument was provided in the set of properties found |
| | | * is a properties file. |
| | | * |
| | | * @return <CODE>true</CODE> if this argument was provided in the set of |
| | | * properties found is a properties file, or <CODE>false</CODE> if |
| | | * not. |
| | | */ |
| | | public boolean isValueSetByProperty() |
| | | { |
| | | return isValueSetByProperty; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether a value must be provided with this argument if it is |
| | | * present. |
| | | * |
| | | * @return <CODE>true</CODE> if a value must be provided with the argument if |
| | | * it is present, or <CODE>false</CODE> if the argument does not take |
| | | * a value and the presence of the argument identifier itself is |
| | | * sufficient to convey the necessary information. |
| | | */ |
| | | public boolean needsValue() |
| | | { |
| | | return needsValue; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies the default value that will be used for this argument if it is |
| | | * not specified on the command line and it is not set from a properties file. |
| | | * |
| | | * @param defaultValue |
| | | * The default value that will be used for this argument if it is not |
| | | * specified on the command line and it is not set from a properties |
| | | * file. |
| | | */ |
| | | public void setDefaultValue(final String defaultValue) |
| | | { |
| | | this.defaultValue = defaultValue; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this argument should be hidden from the usage |
| | | * information. |
| | | * |
| | | * @param isHidden |
| | | * Indicates whether this argument should be hidden from the usage |
| | | * information. |
| | | */ |
| | | public void setHidden(final boolean isHidden) |
| | | { |
| | | this.isHidden = isHidden; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this argument may be provided more than once on the |
| | | * command line to specify multiple values. |
| | | * |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be provided more than once on |
| | | * the command line to specify multiple values. |
| | | */ |
| | | public void setMultiValued(final boolean isMultiValued) |
| | | { |
| | | this.isMultiValued = isMultiValued; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether a value must be provided with this argument if it is |
| | | * present. If this is changed from <CODE>false</CODE> to <CODE>true</CODE>, |
| | | * then a value placeholder must also be provided. |
| | | * |
| | | * @param needsValue |
| | | * Indicates whether a value must be provided with this argument if |
| | | * it is present. |
| | | */ |
| | | public void setNeedsValue(final boolean needsValue) |
| | | { |
| | | this.needsValue = needsValue; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this argument is present in the parsed set of |
| | | * command-line arguments. |
| | | * |
| | | * @param isPresent |
| | | * Indicates whether this argument is present in the set of |
| | | * command-line arguments. |
| | | */ |
| | | public void setPresent(final boolean isPresent) |
| | | { |
| | | this.isPresent = isPresent; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies the name of a property in a properties file that may be used to |
| | | * set the default value for this argument if it is present. |
| | | * |
| | | * @param propertyName |
| | | * The name of a property in a properties file that may be used to |
| | | * set the default value for this argument if it is present. |
| | | */ |
| | | public void setPropertyName(final String propertyName) |
| | | { |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this argument is required to have at least one value. |
| | | * |
| | | * @param isRequired |
| | | * Indicates whether this argument is required to have at least one |
| | | * value. |
| | | */ |
| | | public void setRequired(final boolean isRequired) |
| | | { |
| | | this.isRequired = isRequired; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies the value placeholder that will be displayed for this argument in |
| | | * the generated usage information. It may be <CODE>null</CODE> only if |
| | | * <CODE>needsValue()</CODE> returns <CODE>false</CODE>. |
| | | * |
| | | * @param valuePlaceholder |
| | | * The value placeholder that will be displayed for this argument in |
| | | * the generated usage information. |
| | | */ |
| | | public void setValuePlaceholder(final LocalizableMessage valuePlaceholder) |
| | | { |
| | | this.valuePlaceholder = valuePlaceholder; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether this argument was provided in the set of properties found |
| | | * is a properties file. |
| | | * |
| | | * @param isValueSetByProperty |
| | | * Specify whether this argument was provided in the set of |
| | | * properties found is a properties file. |
| | | */ |
| | | public void setValueSetByProperty(final boolean isValueSetByProperty) |
| | | { |
| | | this.isValueSetByProperty = isValueSetByProperty; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | public abstract boolean valueIsAcceptable(String valueString, |
| | | LocalizableMessageBuilder invalidReason); |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.LocalizableException; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an exception that may be thrown if there is a problem with |
| | | * an argument definition. |
| | | */ |
| | | @SuppressWarnings("serial") |
| | | final class ArgumentException extends Exception implements LocalizableException |
| | | { |
| | | // The I18N message associated with this exception. |
| | | private final LocalizableMessage message; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new argument exception with the provided message. |
| | | * |
| | | * @param message |
| | | * The message that explains the problem that occurred. |
| | | */ |
| | | ArgumentException(final LocalizableMessage message) |
| | | { |
| | | super(String.valueOf(message)); |
| | | this.message = message; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new argument exception with the provided message and root cause. |
| | | * |
| | | * @param message |
| | | * The message that explains the problem that occurred. |
| | | * @param cause |
| | | * The exception that was caught to trigger this exception. |
| | | */ |
| | | ArgumentException(final LocalizableMessage message, final Throwable cause) |
| | | { |
| | | super(String.valueOf(message), cause); |
| | | this.message = message; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public LocalizableMessage getMessageObject() |
| | | { |
| | | return this.message; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Class for organizing options into logical groups when arguement usage is |
| | | * printed. To use an argument group, create an instance and use |
| | | * {@link org.opends.server.util.args.ArgumentParser #addArgument(Argument, ArgumentGroup)} |
| | | * when adding arguments for to the parser. |
| | | */ |
| | | final class ArgumentGroup implements Comparable<ArgumentGroup> |
| | | { |
| | | |
| | | // Description for this group of arguments |
| | | private LocalizableMessage description = null; |
| | | |
| | | // List of arguments belonging to this group |
| | | private List<Argument> args = null; |
| | | |
| | | // Governs groups position within usage statement |
| | | private final Integer priority; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a parameterized instance. |
| | | * |
| | | * @param description |
| | | * for options in this group that is printed before argument |
| | | * descriptions in usage output |
| | | * @param priority |
| | | * number governing the position of this group within the usage |
| | | * statement. Groups with higher priority values appear before groups |
| | | * with lower priority. |
| | | */ |
| | | ArgumentGroup(final LocalizableMessage description, final int priority) |
| | | { |
| | | this.description = description; |
| | | this.priority = priority; |
| | | this.args = new LinkedList<Argument>(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compareTo(final ArgumentGroup o) |
| | | { |
| | | // Groups with higher priority numbers appear before |
| | | // those with lower priority in the usage output |
| | | return -1 * priority.compareTo(o.priority); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds an argument to this group. |
| | | * |
| | | * @param arg |
| | | * to add |
| | | * @return boolean where true indicates the add was successful |
| | | */ |
| | | boolean addArgument(final Argument arg) |
| | | { |
| | | boolean success = false; |
| | | if (arg != null) |
| | | { |
| | | final Character newShort = arg.getShortIdentifier(); |
| | | final String newLong = arg.getLongIdentifier(); |
| | | |
| | | // See if there is already an argument in this group that the |
| | | // new argument should replace |
| | | for (final Iterator<Argument> it = this.args.iterator(); it.hasNext();) |
| | | { |
| | | final Argument a = it.next(); |
| | | if (newShort != null && newShort.equals(a.getShortIdentifier()) |
| | | || newLong != null && newLong.equals(a.getLongIdentifier())) |
| | | { |
| | | it.remove(); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | success = this.args.add(arg); |
| | | } |
| | | return success; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this group contains any members. |
| | | * |
| | | * @return boolean where true means this group contains members |
| | | */ |
| | | boolean containsArguments() |
| | | { |
| | | return this.args.size() > 0; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this group contains any non-hidden members. |
| | | * |
| | | * @return boolean where true means this group contains non-hidden members |
| | | */ |
| | | boolean containsNonHiddenArguments() |
| | | { |
| | | for (final Argument arg : args) |
| | | { |
| | | if (!arg.isHidden()) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the list of arguments associated with this group. |
| | | * |
| | | * @return list of associated arguments |
| | | */ |
| | | List<Argument> getArguments() |
| | | { |
| | | return Collections.unmodifiableList(args); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the description for this group of arguments. |
| | | * |
| | | * @return description for this argument group |
| | | */ |
| | | LocalizableMessage getDescription() |
| | | { |
| | | return this.description; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Removes an argument from this group. |
| | | * |
| | | * @param arg |
| | | * to remove |
| | | * @return boolean where true indicates the remove was successful |
| | | */ |
| | | boolean removeArgument(final Argument arg) |
| | | { |
| | | return this.args.remove(arg); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the description for this group of arguments. |
| | | * |
| | | * @param description |
| | | * for this argument group |
| | | */ |
| | | void setDescription(final LocalizableMessage description) |
| | | { |
| | | this.description = description; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.PROPERTY_SCRIPT_NAME; |
| | | import static com.sun.opends.sdk.tools.Utils.wrapText; |
| | | import static com.sun.opends.sdk.util.StaticUtils.EOL; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getBytes; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage; |
| | | import static com.sun.opends.sdk.util.StaticUtils.toLowerCase; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStream; |
| | | import java.util.*; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a utility that can be used to deal with command-line |
| | | * arguments for applications in a CLIP-compliant manner using either short |
| | | * one-character or longer word-based arguments. It is also integrated with the |
| | | * Directory Server message catalog so that it can display messages in an |
| | | * internationalizeable format, can automatically generate usage information, |
| | | * can detect conflicts between arguments, and can interact with a properties |
| | | * file to obtain default values for arguments there if they are not specified |
| | | * on the command-line. |
| | | */ |
| | | final class ArgumentParser |
| | | { |
| | | /** |
| | | * The argument that will be used to indicate the file properties. |
| | | */ |
| | | private StringArgument filePropertiesPathArgument; |
| | | |
| | | /** |
| | | * The argument that will be used to indicate that we'll not look for default |
| | | * properties file. |
| | | */ |
| | | private BooleanArgument noPropertiesFileArgument; |
| | | |
| | | // The argument that will be used to trigger the display of usage |
| | | // information. |
| | | private Argument usageArgument; |
| | | |
| | | // The argument that will be used to trigger the display of the OpenDS |
| | | // version. |
| | | private Argument versionArgument; |
| | | |
| | | // The set of unnamed trailing arguments that were provided for this |
| | | // parser. |
| | | private final ArrayList<String> trailingArguments; |
| | | |
| | | // Indicates whether this parser will allow additional unnamed |
| | | // arguments at the end of the list. |
| | | private final boolean allowsTrailingArguments; |
| | | |
| | | // Indicates whether long arguments should be treated in a |
| | | // case-sensitive manner. |
| | | private final boolean longArgumentsCaseSensitive; |
| | | |
| | | // Indicates whether the usage or version information has been |
| | | // displayed. |
| | | private boolean usageOrVersionDisplayed; |
| | | |
| | | // Indicates whether the version argument was provided. |
| | | private boolean versionPresent; |
| | | |
| | | // The set of arguments defined for this parser, referenced by short |
| | | // ID. |
| | | private final HashMap<Character, Argument> shortIDMap; |
| | | |
| | | // The set of arguments defined for this parser, referenced by |
| | | // argument name. |
| | | private final HashMap<String, Argument> argumentMap; |
| | | |
| | | // The set of arguments defined for this parser, referenced by long |
| | | // ID. |
| | | private final HashMap<String, Argument> longIDMap; |
| | | |
| | | // The maximum number of unnamed trailing arguments that may be |
| | | // provided. |
| | | private final int maxTrailingArguments; |
| | | |
| | | // The minimum number of unnamed trailing arguments that may be |
| | | // provided. |
| | | private final int minTrailingArguments; |
| | | |
| | | // The total set of arguments defined for this parser. |
| | | private final LinkedList<Argument> argumentList; |
| | | |
| | | // The output stream to which usage information should be printed. |
| | | private OutputStream usageOutputStream; |
| | | |
| | | // The fully-qualified name of the Java class that should be invoked |
| | | // to launch the program with which this argument parser is associated. |
| | | private final String mainClassName; |
| | | |
| | | // A human-readable description for the tool, which will be included |
| | | // when displaying usage information. |
| | | private final LocalizableMessage toolDescription; |
| | | |
| | | // The display name that will be used for the trailing arguments in |
| | | // the usage information. |
| | | private final String trailingArgsDisplayName; |
| | | |
| | | // The raw set of command-line arguments that were provided. |
| | | private String[] rawArguments; |
| | | |
| | | /** Set of argument groups. */ |
| | | private Set<ArgumentGroup> argumentGroups; |
| | | |
| | | /** |
| | | * Group for arguments that have not been explicitly grouped. These will |
| | | * appear at the top of the usage statement without a header. |
| | | */ |
| | | private final ArgumentGroup defaultArgGroup = new ArgumentGroup( |
| | | LocalizableMessage.EMPTY, Integer.MAX_VALUE); |
| | | |
| | | /** |
| | | * Group for arguments that are related to connection through LDAP. This |
| | | * includes options like the bind DN, the port, etc. |
| | | */ |
| | | private final ArgumentGroup ldapArgGroup = new ArgumentGroup( |
| | | INFO_DESCRIPTION_LDAP_CONNECTION_ARGS.get(), Integer.MIN_VALUE + 2); |
| | | |
| | | /** |
| | | * Group for arguments that are related to utility input/output like |
| | | * properties file, no-prompt etc. These will appear toward the bottom of the |
| | | * usage statement. |
| | | */ |
| | | private final ArgumentGroup ioArgGroup = new ArgumentGroup( |
| | | INFO_DESCRIPTION_IO_ARGS.get(), Integer.MIN_VALUE + 1); |
| | | |
| | | /** |
| | | * Group for arguments that are general like help, version etc. These will |
| | | * appear at the end of the usage statement. |
| | | */ |
| | | private final ArgumentGroup generalArgGroup = new ArgumentGroup( |
| | | INFO_DESCRIPTION_GENERAL_ARGS.get(), Integer.MIN_VALUE); |
| | | |
| | | private final static String INDENT = " "; |
| | | |
| | | private final static int MAX_LENGTH = 80; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this argument parser with no arguments. Unnamed |
| | | * trailing arguments will not be allowed. |
| | | * |
| | | * @param mainClassName |
| | | * The fully-qualified name of the Java class that should be invoked |
| | | * to launch the program with which this argument parser is |
| | | * associated. |
| | | * @param toolDescription |
| | | * A human-readable description for the tool, which will be included |
| | | * when displaying usage information. |
| | | * @param longArgumentsCaseSensitive |
| | | * Indicates whether long arguments should be treated in a |
| | | * case-sensitive manner. |
| | | */ |
| | | ArgumentParser(final String mainClassName, |
| | | final LocalizableMessage toolDescription, |
| | | final boolean longArgumentsCaseSensitive) |
| | | { |
| | | this.mainClassName = mainClassName; |
| | | this.toolDescription = toolDescription; |
| | | this.longArgumentsCaseSensitive = longArgumentsCaseSensitive; |
| | | |
| | | argumentList = new LinkedList<Argument>(); |
| | | argumentMap = new HashMap<String, Argument>(); |
| | | shortIDMap = new HashMap<Character, Argument>(); |
| | | longIDMap = new HashMap<String, Argument>(); |
| | | allowsTrailingArguments = false; |
| | | usageOrVersionDisplayed = false; |
| | | versionPresent = false; |
| | | trailingArgsDisplayName = null; |
| | | maxTrailingArguments = 0; |
| | | minTrailingArguments = 0; |
| | | trailingArguments = new ArrayList<String>(); |
| | | rawArguments = null; |
| | | usageArgument = null; |
| | | filePropertiesPathArgument = null; |
| | | noPropertiesFileArgument = null; |
| | | usageOutputStream = System.out; |
| | | initGroups(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this argument parser with no arguments that may |
| | | * or may not be allowed to have unnamed trailing arguments. |
| | | * |
| | | * @param mainClassName |
| | | * The fully-qualified name of the Java class that should be invoked |
| | | * to launch the program with which this argument parser is |
| | | * associated. |
| | | * @param toolDescription |
| | | * A human-readable description for the tool, which will be included |
| | | * when displaying usage information. |
| | | * @param longArgumentsCaseSensitive |
| | | * Indicates whether long arguments should be treated in a |
| | | * case-sensitive manner. |
| | | * @param allowsTrailingArguments |
| | | * Indicates whether this parser allows unnamed trailing arguments to |
| | | * be provided. |
| | | * @param minTrailingArguments |
| | | * The minimum number of unnamed trailing arguments that must be |
| | | * provided. A value less than or equal to zero indicates that no |
| | | * minimum will be enforced. |
| | | * @param maxTrailingArguments |
| | | * The maximum number of unnamed trailing arguments that may be |
| | | * provided. A value less than or equal to zero indicates that no |
| | | * maximum will be enforced. |
| | | * @param trailingArgsDisplayName |
| | | * The display name that should be used as a placeholder for unnamed |
| | | * trailing arguments in the generated usage information. |
| | | */ |
| | | ArgumentParser(final String mainClassName, |
| | | final LocalizableMessage toolDescription, |
| | | final boolean longArgumentsCaseSensitive, |
| | | final boolean allowsTrailingArguments, final int minTrailingArguments, |
| | | final int maxTrailingArguments, final String trailingArgsDisplayName) |
| | | { |
| | | this.mainClassName = mainClassName; |
| | | this.toolDescription = toolDescription; |
| | | this.longArgumentsCaseSensitive = longArgumentsCaseSensitive; |
| | | this.allowsTrailingArguments = allowsTrailingArguments; |
| | | this.minTrailingArguments = minTrailingArguments; |
| | | this.maxTrailingArguments = maxTrailingArguments; |
| | | this.trailingArgsDisplayName = trailingArgsDisplayName; |
| | | |
| | | argumentList = new LinkedList<Argument>(); |
| | | argumentMap = new HashMap<String, Argument>(); |
| | | shortIDMap = new HashMap<Character, Argument>(); |
| | | longIDMap = new HashMap<String, Argument>(); |
| | | trailingArguments = new ArrayList<String>(); |
| | | usageOrVersionDisplayed = false; |
| | | versionPresent = false; |
| | | rawArguments = null; |
| | | usageArgument = null; |
| | | usageOutputStream = System.out; |
| | | initGroups(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @param group |
| | | * The argument group to which the argument belongs. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addArgument(final Argument argument, ArgumentGroup group) |
| | | throws ArgumentException |
| | | { |
| | | |
| | | final Character shortID = argument.getShortIdentifier(); |
| | | if ((shortID != null) && shortIDMap.containsKey(shortID)) |
| | | { |
| | | final String conflictingName = shortIDMap.get(shortID).getName(); |
| | | |
| | | final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get( |
| | | argument.getName(), String.valueOf(shortID), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (versionArgument != null) |
| | | { |
| | | if (shortID != null && |
| | | shortID.equals(versionArgument.getShortIdentifier())) |
| | | { |
| | | // Update the version argument to not display its short |
| | | // identifier. |
| | | try |
| | | { |
| | | versionArgument = new BooleanArgument(OPTION_LONG_PRODUCT_VERSION, |
| | | null, OPTION_LONG_PRODUCT_VERSION, |
| | | INFO_DESCRIPTION_PRODUCT_VERSION.get()); |
| | | this.generalArgGroup.addArgument(versionArgument); |
| | | } |
| | | catch (final ArgumentException e) |
| | | { |
| | | // ignore |
| | | } |
| | | } |
| | | } |
| | | |
| | | String longID = argument.getLongIdentifier(); |
| | | if (longID != null) |
| | | { |
| | | if (!longArgumentsCaseSensitive) |
| | | { |
| | | longID = toLowerCase(longID); |
| | | } |
| | | if (longIDMap.containsKey(longID)) |
| | | { |
| | | final String conflictingName = longIDMap.get(longID).getName(); |
| | | |
| | | final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get( |
| | | argument.getName(), argument.getLongIdentifier(), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | if (shortID != null) |
| | | { |
| | | shortIDMap.put(shortID, argument); |
| | | } |
| | | |
| | | if (longID != null) |
| | | { |
| | | longIDMap.put(longID, argument); |
| | | } |
| | | |
| | | argumentList.add(argument); |
| | | |
| | | if (group == null) |
| | | { |
| | | group = getStandardGroup(argument); |
| | | } |
| | | group.addArgument(argument); |
| | | argumentGroups.add(group); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the arguement in the default group. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addDefaultArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, defaultArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the arguement in the general group. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addGeneralArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, generalArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the argument in the input/output group. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addInputOutputArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, ioArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the argument in the LDAP connection group. |
| | | * |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addLdapConnectionArgument(final Argument argument) |
| | | throws ArgumentException |
| | | { |
| | | addArgument(argument, ldapArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this parser will allow unnamed trailing arguments. These |
| | | * will be arguments at the end of the list that are not preceded by either a |
| | | * long or short identifier and will need to be manually parsed by the |
| | | * application using this parser. Note that once an unnamed trailing argument |
| | | * has been identified, all remaining arguments will be classified as such. |
| | | * |
| | | * @return <CODE>true</CODE> if this parser allows unnamed trailing arguments, |
| | | * or <CODE>false</CODE> if it does not. |
| | | */ |
| | | boolean allowsTrailingArguments() |
| | | { |
| | | return allowsTrailingArguments; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Check if we have a properties file. |
| | | * |
| | | * @return The properties found in the properties file or null. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments. |
| | | */ |
| | | Properties checkExternalProperties() throws ArgumentException |
| | | { |
| | | // We don't look for properties file. |
| | | if ((noPropertiesFileArgument != null) |
| | | && (noPropertiesFileArgument.isPresent())) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | // Check if we have a properties file argument |
| | | if (filePropertiesPathArgument == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | // check if the properties file argument has been set. If not |
| | | // look for default location. |
| | | String propertiesFilePath = null; |
| | | if (filePropertiesPathArgument.isPresent()) |
| | | { |
| | | propertiesFilePath = filePropertiesPathArgument.getValue(); |
| | | } |
| | | else |
| | | { |
| | | // Check in "user home"/.opends directory |
| | | final String userDir = System.getProperty("user.home"); |
| | | propertiesFilePath = findPropertiesFile(userDir + File.separator |
| | | + DEFAULT_OPENDS_CONFIG_DIR); |
| | | |
| | | // TODO |
| | | /* |
| | | * if (propertiesFilePath == null) { // check "Opends instance"/config |
| | | * directory String instanceDir = DirectoryServer.getInstanceRoot(); |
| | | * propertiesFilePath = findPropertiesFile(instanceDir+ File.separator + |
| | | * "config"); } |
| | | */ |
| | | } |
| | | |
| | | // We don't have a properties file location |
| | | if (propertiesFilePath == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | // We have a location for the properties file. |
| | | final Properties argumentProperties = new Properties(); |
| | | final String scriptName = System.getProperty(Utils.PROPERTY_SCRIPT_NAME); |
| | | try |
| | | { |
| | | final Properties p = new Properties(); |
| | | final FileInputStream fis = new FileInputStream(propertiesFilePath); |
| | | p.load(fis); |
| | | fis.close(); |
| | | |
| | | for (final Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) |
| | | { |
| | | final String currentPropertyName = (String) e.nextElement(); |
| | | String propertyName = currentPropertyName; |
| | | |
| | | // Property name form <script name>.<property name> has the |
| | | // precedence to <property name> |
| | | if (scriptName != null) |
| | | { |
| | | if (currentPropertyName.startsWith(scriptName)) |
| | | { |
| | | propertyName = currentPropertyName |
| | | .substring(scriptName.length() + 1); |
| | | } |
| | | else |
| | | { |
| | | if (p.containsKey(scriptName + "." + currentPropertyName)) |
| | | { |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | argumentProperties.setProperty(propertyName.toLowerCase(), p |
| | | .getProperty(currentPropertyName)); |
| | | } |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE |
| | | .get(String.valueOf(propertiesFilePath), getExceptionMessage(e)); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | return argumentProperties; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the argument with the specified name. |
| | | * |
| | | * @param name |
| | | * The name of the argument to retrieve. |
| | | * @return The argument with the specified name, or <CODE>null</CODE> if there |
| | | * is no such argument. |
| | | */ |
| | | Argument getArgument(final String name) |
| | | { |
| | | return argumentMap.get(name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the argument with the specified long identifier. |
| | | * |
| | | * @param longID |
| | | * The long identifier of the argument to retrieve. |
| | | * @return The argument with the specified long identifier, or |
| | | * <CODE>null</CODE> if there is no such argument. |
| | | */ |
| | | Argument getArgumentForLongID(final String longID) |
| | | { |
| | | return longIDMap.get(longID); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the argument with the specified short identifier. |
| | | * |
| | | * @param shortID |
| | | * The short ID for the argument to retrieve. |
| | | * @return The argument with the specified short identifier, or |
| | | * <CODE>null</CODE> if there is no such argument. |
| | | */ |
| | | Argument getArgumentForShortID(final Character shortID) |
| | | { |
| | | return shortIDMap.get(shortID); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the list of all arguments that have been defined for this |
| | | * argument parser. |
| | | * |
| | | * @return The list of all arguments that have been defined for this argument |
| | | * parser. |
| | | */ |
| | | LinkedList<Argument> getArgumentList() |
| | | { |
| | | return argumentList; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of arguments mapped by the long identifier that may be |
| | | * used to reference them. Note that arguments that do not have a long |
| | | * identifier will not be present in this list. |
| | | * |
| | | * @return The set of arguments mapped by the long identifier that may be used |
| | | * to reference them. |
| | | */ |
| | | HashMap<String, Argument> getArgumentsByLongID() |
| | | { |
| | | return longIDMap; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of arguments mapped by the short identifier that may be |
| | | * used to reference them. Note that arguments that do not have a short |
| | | * identifier will not be present in this list. |
| | | * |
| | | * @return The set of arguments mapped by the short identifier that may be |
| | | * used to reference them. |
| | | */ |
| | | HashMap<Character, Argument> getArgumentsByShortID() |
| | | { |
| | | return shortIDMap; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the fully-qualified name of the Java class that should be invoked |
| | | * to launch the program with which this argument parser is associated. |
| | | * |
| | | * @return The fully-qualified name of the Java class that should be invoked |
| | | * to launch the program with which this argument parser is |
| | | * associated. |
| | | */ |
| | | String getMainClassName() |
| | | { |
| | | return mainClassName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the maximum number of unnamed trailing arguments that may be |
| | | * provided. |
| | | * |
| | | * @return The maximum number of unnamed trailing arguments that may be |
| | | * provided, or a value less than or equal to zero if no maximum will |
| | | * be enforced. |
| | | */ |
| | | int getMaxTrailingArguments() |
| | | { |
| | | return maxTrailingArguments; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the minimum number of unnamed trailing arguments that must be |
| | | * provided. |
| | | * |
| | | * @return The minimum number of unnamed trailing arguments that must be |
| | | * provided, or a value less than or equal to zero if no minimum will |
| | | * be enforced. |
| | | */ |
| | | int getMinTrailingArguments() |
| | | { |
| | | return minTrailingArguments; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the raw set of arguments that were provided. |
| | | * |
| | | * @return The raw set of arguments that were provided, or <CODE>null</CODE> |
| | | * if the argument list has not yet been parsed. |
| | | */ |
| | | String[] getRawArguments() |
| | | { |
| | | return rawArguments; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Given an argument, returns an appropriate group. Arguments may be part of |
| | | * one of the special groups or the default group. |
| | | * |
| | | * @param argument |
| | | * for which a group is requested |
| | | * @return argument group appropriate for <code>argument</code> |
| | | */ |
| | | ArgumentGroup getStandardGroup(final Argument argument) |
| | | { |
| | | ArgumentGroup group; |
| | | if (isInputOutputArgument(argument)) |
| | | { |
| | | group = ioArgGroup; |
| | | } |
| | | else if (isGeneralArgument(argument)) |
| | | { |
| | | group = generalArgGroup; |
| | | } |
| | | else if (isLdapConnectionArgument(argument)) |
| | | { |
| | | group = ldapArgGroup; |
| | | } |
| | | else |
| | | { |
| | | group = defaultArgGroup; |
| | | } |
| | | return group; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a human-readable description for this tool, which should be |
| | | * included at the top of the command-line usage information. |
| | | * |
| | | * @return A human-readable description for this tool, or {@code null} if none |
| | | * is available. |
| | | */ |
| | | LocalizableMessage getToolDescription() |
| | | { |
| | | return toolDescription; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of unnamed trailing arguments that were provided on the |
| | | * command line. |
| | | * |
| | | * @return The set of unnamed trailing arguments that were provided on the |
| | | * command line. |
| | | */ |
| | | ArrayList<String> getTrailingArguments() |
| | | { |
| | | return trailingArguments; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string containing usage information based on the defined |
| | | * arguments. |
| | | * |
| | | * @return A string containing usage information based on the defined |
| | | * arguments. |
| | | */ |
| | | String getUsage() |
| | | { |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Writes usage information based on the defined arguments to the provided |
| | | * output stream. |
| | | * |
| | | * @param outputStream |
| | | * The output stream to which the usage information should be |
| | | * written. |
| | | * @throws IOException |
| | | * If a problem occurs while attempting to write the usage |
| | | * information to the provided output stream. |
| | | */ |
| | | void getUsage(final OutputStream outputStream) throws IOException |
| | | { |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | outputStream.write(getBytes(buffer.toString())); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends usage information based on the defined arguments to the provided |
| | | * buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to which the usage information should be appended. |
| | | */ |
| | | void getUsage(final StringBuilder buffer) |
| | | { |
| | | usageOrVersionDisplayed = true; |
| | | if ((toolDescription != null) && (toolDescription.length() > 0)) |
| | | { |
| | | buffer.append(wrapText(toolDescription.toString(), MAX_LENGTH - 1)); |
| | | buffer.append(EOL); |
| | | buffer.append(EOL); |
| | | } |
| | | |
| | | final String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | | if ((scriptName == null) || (scriptName.length() == 0)) |
| | | { |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_CLASSNAME.get(mainClassName)); |
| | | } |
| | | else |
| | | { |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME.get(scriptName)); |
| | | } |
| | | |
| | | if (allowsTrailingArguments) |
| | | { |
| | | if (trailingArgsDisplayName == null) |
| | | { |
| | | buffer.append(" " + INFO_ARGPARSER_USAGE_TRAILINGARGS.get()); |
| | | } |
| | | else |
| | | { |
| | | buffer.append(" "); |
| | | buffer.append(trailingArgsDisplayName); |
| | | } |
| | | } |
| | | buffer.append(EOL); |
| | | buffer.append(EOL); |
| | | buffer.append(INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get()); |
| | | buffer.append(EOL); |
| | | buffer.append(EOL); |
| | | |
| | | Argument helpArgument = null; |
| | | |
| | | final boolean printHeaders = printUsageGroupHeaders(); |
| | | for (final ArgumentGroup argGroup : argumentGroups) |
| | | { |
| | | if (argGroup.containsArguments() && printHeaders) |
| | | { |
| | | // Print the groups description if any |
| | | final LocalizableMessage groupDesc = argGroup.getDescription(); |
| | | if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc)) |
| | | { |
| | | buffer.append(EOL); |
| | | buffer.append(wrapText(groupDesc.toString(), MAX_LENGTH - 1)); |
| | | buffer.append(EOL); |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | |
| | | final SortedSet<Argument> args = new TreeSet<Argument>( |
| | | new Comparator<Argument>() |
| | | { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(final Argument o1, final Argument o2) |
| | | { |
| | | final String s1; |
| | | final String s2; |
| | | |
| | | if (o1.getShortIdentifier() != null) |
| | | { |
| | | s1 = o1.getShortIdentifier().toString(); |
| | | } |
| | | else |
| | | { |
| | | s1 = o1.getLongIdentifier(); |
| | | } |
| | | |
| | | if (o2.getShortIdentifier() != null) |
| | | { |
| | | s2 = o2.getShortIdentifier().toString(); |
| | | } |
| | | else |
| | | { |
| | | s2 = o2.getLongIdentifier(); |
| | | } |
| | | |
| | | final int res = s1.compareToIgnoreCase(s2); |
| | | if (res != 0) |
| | | { |
| | | return res; |
| | | } |
| | | else |
| | | { |
| | | // Lowercase options first then uppercase. |
| | | return -s1.compareTo(s2); |
| | | } |
| | | } |
| | | |
| | | }); |
| | | args.addAll(argGroup.getArguments()); |
| | | |
| | | for (final Argument a : args) |
| | | { |
| | | // If this argument is hidden, then skip it. |
| | | if (a.isHidden()) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | // Help argument should be printed at the end |
| | | if ((usageArgument != null) |
| | | && usageArgument.getName().equals(a.getName())) |
| | | { |
| | | helpArgument = a; |
| | | continue; |
| | | } |
| | | printArgumentUsage(a, buffer); |
| | | } |
| | | } |
| | | if (helpArgument != null) |
| | | { |
| | | printArgumentUsage(helpArgument, buffer); |
| | | } |
| | | else |
| | | { |
| | | buffer.append(EOL); |
| | | buffer.append("-?"); |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a message containing usage information based on the defined |
| | | * arguments. |
| | | * |
| | | * @return A string containing usage information based on the defined |
| | | * arguments. |
| | | */ |
| | | LocalizableMessage getUsageMessage() |
| | | { |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | // TODO: rework getUsage(OutputStream) to work with messages |
| | | // framework |
| | | return LocalizableMessage.raw(buffer.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns whether the usage argument was provided or not. This method should |
| | | * be called after a call to parseArguments. |
| | | * |
| | | * @return <CODE>true</CODE> if the usage argument was provided and |
| | | * <CODE>false</CODE> otherwise. |
| | | */ |
| | | boolean isUsageArgumentPresent() |
| | | { |
| | | boolean isUsageArgumentPresent = false; |
| | | if (usageArgument != null) |
| | | { |
| | | isUsageArgumentPresent = usageArgument.isPresent(); |
| | | } |
| | | return isUsageArgumentPresent; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns whether the version argument was provided or not. This method |
| | | * should be called after a call to parseArguments. |
| | | * |
| | | * @return <CODE>true</CODE> if the version argument was provided and |
| | | * <CODE>false</CODE> otherwise. |
| | | */ |
| | | boolean isVersionArgumentPresent() |
| | | { |
| | | return versionPresent; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided set of arguments and updates the information associated |
| | | * with this parser accordingly. |
| | | * |
| | | * @param rawArguments |
| | | * The raw set of arguments to parse. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments. |
| | | */ |
| | | void parseArguments(final String[] rawArguments) throws ArgumentException |
| | | { |
| | | parseArguments(rawArguments, null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided set of arguments and updates the information associated |
| | | * with this parser accordingly. Default values for unspecified arguments may |
| | | * be read from the specified properties if any are provided. |
| | | * |
| | | * @param rawArguments |
| | | * The set of raw arguments to parse. |
| | | * @param argumentProperties |
| | | * A set of properties that may be used to provide default values for |
| | | * arguments not included in the given raw arguments. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments. |
| | | */ |
| | | void parseArguments(final String[] rawArguments, Properties argumentProperties) |
| | | throws ArgumentException |
| | | { |
| | | this.rawArguments = rawArguments; |
| | | |
| | | boolean inTrailingArgs = false; |
| | | |
| | | final int numArguments = rawArguments.length; |
| | | for (int i = 0; i < numArguments; i++) |
| | | { |
| | | final String arg = rawArguments[i]; |
| | | |
| | | if (inTrailingArgs) |
| | | { |
| | | trailingArguments.add(arg); |
| | | if ((maxTrailingArguments > 0) |
| | | && (trailingArguments.size() > maxTrailingArguments)) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS |
| | | .get(maxTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | |
| | | if (arg.equals("--")) |
| | | { |
| | | // This is a special indicator that we have reached the end of |
| | | // the named arguments and that everything that follows after this |
| | | // should be considered trailing arguments. |
| | | inTrailingArgs = true; |
| | | } |
| | | else if (arg.startsWith("--")) |
| | | { |
| | | // This indicates that we are using the long name to reference |
| | | // the argument. It may be in any of the following forms: |
| | | // --name |
| | | // --name value |
| | | // --name=value |
| | | |
| | | String argName = arg.substring(2); |
| | | String argValue = null; |
| | | final int equalPos = argName.indexOf('='); |
| | | if (equalPos < 0) |
| | | { |
| | | // This is fine. The value is not part of the argument name |
| | | // token. |
| | | } |
| | | else if (equalPos == 0) |
| | | { |
| | | // The argument starts with "--=", which is not acceptable. |
| | | final LocalizableMessage message = ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME |
| | | .get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | | { |
| | | // The argument is in the form --name=value, so parse them |
| | | // both out. |
| | | argValue = argName.substring(equalPos + 1); |
| | | argName = argName.substring(0, equalPos); |
| | | } |
| | | |
| | | // If we're not case-sensitive, then convert the name to |
| | | // lowercase. |
| | | final String origArgName = argName; |
| | | if (!longArgumentsCaseSensitive) |
| | | { |
| | | argName = toLowerCase(argName); |
| | | } |
| | | |
| | | // Get the argument with the specified name. |
| | | final Argument a = longIDMap.get(argName); |
| | | if (a == null) |
| | | { |
| | | if (argName.equals(OPTION_LONG_HELP)) |
| | | { |
| | | // "--help" will always be interpreted as requesting usage |
| | | // information. |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | else if (argName.equals(OPTION_LONG_PRODUCT_VERSION)) |
| | | { |
| | | // "--version" will always be interpreted as requesting |
| | | // version information. |
| | | usageOrVersionDisplayed = true; |
| | | versionPresent = true; |
| | | try |
| | | { |
| | | // TODO |
| | | // DirectoryServer.printVersion(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | a.setPresent(true); |
| | | |
| | | // If this is the usage argument, then immediately stop and |
| | | // print usage information. |
| | | if ((usageArgument != null) |
| | | && usageArgument.getName().equals(a.getName())) |
| | | { |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // See if the argument takes a value. If so, then make sure one |
| | | // was provided. If not, then make sure none was provided. |
| | | if (a.needsValue()) |
| | | { |
| | | if (argValue == null) |
| | | { |
| | | if ((i + 1) == numArguments) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (!a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID |
| | | .get(argValue, origArgName, invalidReason.toString()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | // If the argument already has a value, then make sure it is |
| | | // acceptable to have more than one. |
| | | if (a.hasValue() && (!a.isMultiValued())) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | a.addValue(argValue); |
| | | } |
| | | else |
| | | { |
| | | if (argValue != null) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | } |
| | | else if (arg.startsWith("-")) |
| | | { |
| | | // This indicates that we are using the 1-character name to |
| | | // reference the argument. It may be in any of the following forms: |
| | | // -n |
| | | // -nvalue |
| | | // -n value |
| | | if (arg.equals("-")) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT |
| | | .get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | final char argCharacter = arg.charAt(1); |
| | | String argValue; |
| | | if (arg.length() > 2) |
| | | { |
| | | argValue = arg.substring(2); |
| | | } |
| | | else |
| | | { |
| | | argValue = null; |
| | | } |
| | | |
| | | // Get the argument with the specified short ID. |
| | | final Argument a = shortIDMap.get(argCharacter); |
| | | if (a == null) |
| | | { |
| | | if (argCharacter == '?') |
| | | { |
| | | // "-?" will always be interpreted as requesting usage |
| | | // information. |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | else if ((argCharacter == OPTION_SHORT_PRODUCT_VERSION) |
| | | && (!shortIDMap.containsKey(OPTION_SHORT_PRODUCT_VERSION))) |
| | | { |
| | | // "-V" will always be interpreted as requesting |
| | | // version information except if it's already defined (e.g |
| | | // in ldap tools). |
| | | usageOrVersionDisplayed = true; |
| | | versionPresent = true; |
| | | try |
| | | { |
| | | // TODO |
| | | // DirectoryServer.printVersion(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID |
| | | .get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | a.setPresent(true); |
| | | |
| | | // If this is the usage argument, then immediately stop and |
| | | // print usage information. |
| | | if ((usageArgument != null) |
| | | && usageArgument.getName().equals(a.getName())) |
| | | { |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // See if the argument takes a value. If so, then make sure one |
| | | // was provided. If not, then make sure none was provided. |
| | | if (a.needsValue()) |
| | | { |
| | | if (argValue == null) |
| | | { |
| | | if ((i + 1) == numArguments) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID |
| | | .get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (!a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID |
| | | .get(argValue, String.valueOf(argCharacter), invalidReason |
| | | .toString()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | // If the argument already has a value, then make sure it is |
| | | // acceptable to have more than one. |
| | | if (a.hasValue() && (!a.isMultiValued())) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID |
| | | .get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | a.addValue(argValue); |
| | | } |
| | | else |
| | | { |
| | | if (argValue != null) |
| | | { |
| | | // If we've gotten here, then it means that we're in a scenario like |
| | | // "-abc" where "a" is a valid argument that doesn't take a |
| | | // value. However, this could still be valid if all remaining |
| | | // characters in the value are also valid argument characters that |
| | | // don't take values. |
| | | final int valueLength = argValue.length(); |
| | | for (int j = 0; j < valueLength; j++) |
| | | { |
| | | final char c = argValue.charAt(j); |
| | | final Argument b = shortIDMap.get(c); |
| | | if (b == null) |
| | | { |
| | | // There is no such argument registered. |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID |
| | | .get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else if (b.needsValue()) |
| | | { |
| | | // This means we're in a scenario like "-abc" where b is |
| | | // a valid argument that takes a value. We don't support |
| | | // that. |
| | | final LocalizableMessage message = ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES |
| | | .get(String.valueOf(argCharacter), argValue, String |
| | | .valueOf(c)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | | { |
| | | b.setPresent(true); |
| | | |
| | | // If this is the usage argument, then immediately stop |
| | | // and print usage information. |
| | | if ((usageArgument != null) |
| | | && usageArgument.getName().equals(b.getName())) |
| | | { |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else if (allowsTrailingArguments) |
| | | { |
| | | // It doesn't start with a dash, so it must be a trailing |
| | | // argument if that is acceptable. |
| | | inTrailingArgs = true; |
| | | trailingArguments.add(arg); |
| | | } |
| | | else |
| | | { |
| | | // It doesn't start with a dash and we don't allow trailing |
| | | // arguments, so this is illegal. |
| | | final LocalizableMessage message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT |
| | | .get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | // If we allow trailing arguments and there is a minimum number, |
| | | // then make sure at least that many were provided. |
| | | if (allowsTrailingArguments && (minTrailingArguments > 0)) |
| | | { |
| | | if (trailingArguments.size() < minTrailingArguments) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS |
| | | .get(minTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | // If we don't have the argumentProperties, try to load a properties |
| | | // file. |
| | | if (argumentProperties == null) |
| | | { |
| | | argumentProperties = checkExternalProperties(); |
| | | } |
| | | |
| | | // Iterate through all of the arguments. For any that were not |
| | | // provided on the command line, see if there is an alternate default that |
| | | // can be used. For cases where there is not, see that argument is required. |
| | | for (final Argument a : argumentList) |
| | | { |
| | | if (!a.isPresent()) |
| | | { |
| | | // See if there is a value in the properties that can be used |
| | | if ((argumentProperties != null) && (a.getPropertyName() != null)) |
| | | { |
| | | final String value = argumentProperties.getProperty(a |
| | | .getPropertyName().toLowerCase()); |
| | | final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (value != null) |
| | | { |
| | | Boolean addValue = true; |
| | | if (!(a instanceof BooleanArgument)) |
| | | { |
| | | addValue = a.valueIsAcceptable(value, invalidReason); |
| | | } |
| | | if (addValue) |
| | | { |
| | | a.addValue(value); |
| | | if (a.needsValue()) |
| | | { |
| | | a.setPresent(true); |
| | | } |
| | | a.setValueSetByProperty(true); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ((!a.isPresent()) && a.needsValue()) |
| | | { |
| | | // See if the argument defines a default. |
| | | if (a.getDefaultValue() != null) |
| | | { |
| | | a.addValue(a.getDefaultValue()); |
| | | } |
| | | |
| | | // If there is still no value and the argument is required, then |
| | | // that's a problem. |
| | | if ((!a.hasValue()) && a.isRequired()) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG |
| | | .get(a.getName()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided set of arguments and updates the information associated |
| | | * with this parser accordingly. Default values for unspecified arguments may |
| | | * be read from the specified properties file. |
| | | * |
| | | * @param rawArguments |
| | | * The set of raw arguments to parse. |
| | | * @param propertiesFile |
| | | * The path to the properties file to use to obtain default values |
| | | * for unspecified properties. |
| | | * @param requirePropertiesFile |
| | | * Indicates whether the parsing should fail if the provided |
| | | * properties file does not exist or is not accessible. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided arguments |
| | | * or interacting with the properties file. |
| | | */ |
| | | void parseArguments(final String[] rawArguments, final String propertiesFile, |
| | | final boolean requirePropertiesFile) throws ArgumentException |
| | | { |
| | | this.rawArguments = rawArguments; |
| | | |
| | | Properties argumentProperties = null; |
| | | |
| | | try |
| | | { |
| | | final Properties p = new Properties(); |
| | | final FileInputStream fis = new FileInputStream(propertiesFile); |
| | | p.load(fis); |
| | | fis.close(); |
| | | argumentProperties = p; |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | if (requirePropertiesFile) |
| | | { |
| | | final LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE |
| | | .get(String.valueOf(propertiesFile), getExceptionMessage(e)); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | } |
| | | |
| | | parseArguments(rawArguments, argumentProperties); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not argument group description headers should be |
| | | * printed. |
| | | * |
| | | * @return boolean where true means print the descriptions |
| | | */ |
| | | boolean printUsageGroupHeaders() |
| | | { |
| | | // If there is only a single group then we won't print them. |
| | | int groupsContainingArgs = 0; |
| | | for (final ArgumentGroup argGroup : argumentGroups) |
| | | { |
| | | if (argGroup.containsNonHiddenArguments()) |
| | | { |
| | | groupsContainingArgs++; |
| | | } |
| | | } |
| | | return groupsContainingArgs > 1; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the default argument group. |
| | | * |
| | | * @param description |
| | | * for the default group |
| | | */ |
| | | void setDefaultArgumentGroupDescription(final LocalizableMessage description) |
| | | { |
| | | this.defaultArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the provided argument which will be used to identify the file |
| | | * properties. |
| | | * |
| | | * @param argument |
| | | * The argument which will be used to identify the file properties. |
| | | */ |
| | | void setFilePropertiesArgument(final StringArgument argument) |
| | | { |
| | | filePropertiesPathArgument = argument; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the general argument group. |
| | | * |
| | | * @param description |
| | | * for the general group |
| | | */ |
| | | void setGeneralArgumentGroupDescription(final LocalizableMessage description) |
| | | { |
| | | this.generalArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the input/output argument group. |
| | | * |
| | | * @param description |
| | | * for the input/output group |
| | | */ |
| | | void setInputOutputArgumentGroupDescription( |
| | | final LocalizableMessage description) |
| | | { |
| | | this.ioArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the LDAP argument group. |
| | | * |
| | | * @param description |
| | | * for the LDAP group |
| | | */ |
| | | void setLdapArgumentGroupDescription(final LocalizableMessage description) |
| | | { |
| | | this.ldapArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the provided argument which will be used to identify the file |
| | | * properties. |
| | | * |
| | | * @param argument |
| | | * The argument which will be used to indicate if we have to look for |
| | | * properties file. |
| | | */ |
| | | void setNoPropertiesFileArgument(final BooleanArgument argument) |
| | | { |
| | | noPropertiesFileArgument = argument; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the provided argument as one which will automatically trigger the |
| | | * output of usage information if it is provided on the command line and no |
| | | * further argument validation will be performed. Note that the caller will |
| | | * still need to add this argument to the parser with the |
| | | * <CODE>addArgument</CODE> method, and the argument should not be required |
| | | * and should not take a value. Also, the caller will still need to check for |
| | | * the presence of the usage argument after calling |
| | | * <CODE>parseArguments</CODE> to know that no further processing will be |
| | | * required. |
| | | * |
| | | * @param argument |
| | | * The argument whose presence should automatically trigger the |
| | | * display of usage information. |
| | | */ |
| | | void setUsageArgument(final Argument argument) |
| | | { |
| | | usageArgument = argument; |
| | | usageOutputStream = System.out; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the provided argument as one which will automatically trigger the |
| | | * output of usage information if it is provided on the command line and no |
| | | * further argument validation will be performed. Note that the caller will |
| | | * still need to add this argument to the parser with the |
| | | * <CODE>addArgument</CODE> method, and the argument should not be required |
| | | * and should not take a value. Also, the caller will still need to check for |
| | | * the presence of the usage argument after calling |
| | | * <CODE>parseArguments</CODE> to know that no further processing will be |
| | | * required. |
| | | * |
| | | * @param argument |
| | | * The argument whose presence should automatically trigger the |
| | | * display of usage information. |
| | | * @param outputStream |
| | | * The output stream to which the usage information should be |
| | | * written. |
| | | */ |
| | | void setUsageArgument(final Argument argument, final OutputStream outputStream) |
| | | { |
| | | usageArgument = argument; |
| | | usageOutputStream = outputStream; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the version or the usage information has been displayed |
| | | * to the end user either by an explicit argument like "-H" or "--help", or by |
| | | * a built-in argument like "-?". |
| | | * |
| | | * @return {@code true} if the usage information has been displayed, or |
| | | * {@code false} if not. |
| | | */ |
| | | boolean usageOrVersionDisplayed() |
| | | { |
| | | return usageOrVersionDisplayed; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the absolute path of the properties file. |
| | | * |
| | | * @param directory |
| | | * The location in which we should look for properties file |
| | | * @return The absolute path of the properties file or null |
| | | */ |
| | | private String findPropertiesFile(final String directory) |
| | | { |
| | | // Look for the tools properties file |
| | | final File f = new File(directory, DEFAULT_OPENDS_PROPERTIES_FILE_NAME |
| | | + DEFAULT_OPENDS_PROPERTIES_FILE_EXTENSION); |
| | | if (f.exists() && f.canRead()) |
| | | { |
| | | return f.getAbsolutePath(); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private void initGroups() |
| | | { |
| | | this.argumentGroups = new TreeSet<ArgumentGroup>(); |
| | | this.argumentGroups.add(defaultArgGroup); |
| | | this.argumentGroups.add(ldapArgGroup); |
| | | this.argumentGroups.add(generalArgGroup); |
| | | this.argumentGroups.add(ioArgGroup); |
| | | |
| | | try |
| | | { |
| | | versionArgument = new BooleanArgument(OPTION_LONG_PRODUCT_VERSION, |
| | | OPTION_SHORT_PRODUCT_VERSION, OPTION_LONG_PRODUCT_VERSION, |
| | | INFO_DESCRIPTION_PRODUCT_VERSION.get()); |
| | | this.generalArgGroup.addArgument(versionArgument); |
| | | } |
| | | catch (final ArgumentException e) |
| | | { |
| | | // ignore |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean isGeneralArgument(final Argument arg) |
| | | { |
| | | boolean general = false; |
| | | if (arg != null) |
| | | { |
| | | final String longId = arg.getLongIdentifier(); |
| | | general = OPTION_LONG_HELP.equals(longId) |
| | | || OPTION_LONG_PRODUCT_VERSION.equals(longId); |
| | | } |
| | | return general; |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean isInputOutputArgument(final Argument arg) |
| | | { |
| | | boolean io = false; |
| | | if (arg != null) |
| | | { |
| | | final String longId = arg.getLongIdentifier(); |
| | | io = OPTION_LONG_VERBOSE.equals(longId) |
| | | || OPTION_LONG_QUIET.equals(longId) |
| | | || OPTION_LONG_NO_PROMPT.equals(longId) |
| | | || OPTION_LONG_PROP_FILE_PATH.equals(longId) |
| | | || OPTION_LONG_NO_PROP_FILE.equals(longId) |
| | | || OPTION_LONG_SCRIPT_FRIENDLY.equals(longId) |
| | | || OPTION_LONG_DONT_WRAP.equals(longId) |
| | | || OPTION_LONG_ENCODING.equals(longId) |
| | | || OPTION_LONG_BATCH_FILE_PATH.equals(longId); |
| | | } |
| | | return io; |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean isLdapConnectionArgument(final Argument arg) |
| | | { |
| | | boolean ldap = false; |
| | | if (arg != null) |
| | | { |
| | | final String longId = arg.getLongIdentifier(); |
| | | ldap = OPTION_LONG_USE_SSL.equals(longId) |
| | | || OPTION_LONG_START_TLS.equals(longId) |
| | | || OPTION_LONG_HOST.equals(longId) || OPTION_LONG_PORT.equals(longId) |
| | | || OPTION_LONG_BINDDN.equals(longId) |
| | | || OPTION_LONG_BINDPWD.equals(longId) |
| | | || OPTION_LONG_BINDPWD_FILE.equals(longId) |
| | | || OPTION_LONG_SASLOPTION.equals(longId) |
| | | || OPTION_LONG_TRUSTALL.equals(longId) |
| | | || OPTION_LONG_TRUSTSTOREPATH.equals(longId) |
| | | || OPTION_LONG_TRUSTSTORE_PWD.equals(longId) |
| | | || OPTION_LONG_TRUSTSTORE_PWD_FILE.equals(longId) |
| | | || OPTION_LONG_KEYSTOREPATH.equals(longId) |
| | | || OPTION_LONG_KEYSTORE_PWD.equals(longId) |
| | | || OPTION_LONG_KEYSTORE_PWD_FILE.equals(longId) |
| | | || OPTION_LONG_CERT_NICKNAME.equals(longId) |
| | | || OPTION_LONG_REFERENCED_HOST_NAME.equals(longId) |
| | | || OPTION_LONG_ADMIN_UID.equals(longId) |
| | | || OPTION_LONG_REPORT_AUTHZ_ID.equals(longId) |
| | | || OPTION_LONG_USE_PW_POLICY_CTL.equals(longId) |
| | | || OPTION_LONG_USE_SASL_EXTERNAL.equals(longId) |
| | | || OPTION_LONG_PROTOCOL_VERSION.equals(longId); |
| | | } |
| | | return ldap; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends argument usage information to the provided buffer. |
| | | * |
| | | * @param a |
| | | * The argument to handle. |
| | | * @param buffer |
| | | * The buffer to which the usage information should be appended. |
| | | */ |
| | | private void printArgumentUsage(final Argument a, final StringBuilder buffer) |
| | | { |
| | | // Write a line with the short and/or long identifiers that may be |
| | | // used |
| | | // for the argument. |
| | | final int indentLength = INDENT.length(); |
| | | final Character shortID = a.getShortIdentifier(); |
| | | final String longID = a.getLongIdentifier(); |
| | | if (shortID != null) |
| | | { |
| | | final int currentLength = buffer.length(); |
| | | |
| | | if (usageArgument.getName().equals(a.getName())) |
| | | { |
| | | buffer.append("-?, "); |
| | | } |
| | | |
| | | buffer.append("-"); |
| | | buffer.append(shortID.charValue()); |
| | | |
| | | if (a.needsValue() && longID == null) |
| | | { |
| | | buffer.append(" "); |
| | | buffer.append(a.getValuePlaceholder()); |
| | | } |
| | | |
| | | if (longID != null) |
| | | { |
| | | final StringBuilder newBuffer = new StringBuilder(); |
| | | newBuffer.append(", --"); |
| | | newBuffer.append(longID); |
| | | |
| | | if (a.needsValue()) |
| | | { |
| | | newBuffer.append(" "); |
| | | newBuffer.append(a.getValuePlaceholder()); |
| | | } |
| | | |
| | | final int lineLength = (buffer.length() - currentLength) |
| | | + newBuffer.length(); |
| | | if (lineLength > MAX_LENGTH) |
| | | { |
| | | buffer.append(EOL); |
| | | buffer.append(newBuffer.toString()); |
| | | } |
| | | else |
| | | { |
| | | buffer.append(newBuffer.toString()); |
| | | } |
| | | } |
| | | |
| | | buffer.append(EOL); |
| | | } |
| | | else |
| | | { |
| | | if (longID != null) |
| | | { |
| | | if (usageArgument.getName().equals(a.getName())) |
| | | { |
| | | buffer.append("-?, "); |
| | | } |
| | | buffer.append("--"); |
| | | buffer.append(longID); |
| | | |
| | | if (a.needsValue()) |
| | | { |
| | | buffer.append(" "); |
| | | buffer.append(a.getValuePlaceholder()); |
| | | } |
| | | |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | |
| | | // Write one or more lines with the description of the argument. |
| | | // We will |
| | | // indent the description five characters and try our best to wrap |
| | | // at or |
| | | // before column 79 so it will be friendly to 80-column displays. |
| | | buffer.append( |
| | | Utils.wrapText(a.getDescription(), MAX_LENGTH, indentLength)); |
| | | buffer.append(EOL); |
| | | |
| | | if (a.needsValue() && (a.getDefaultValue() != null) |
| | | && (a.getDefaultValue().length() > 0)) |
| | | { |
| | | buffer.append(INDENT); |
| | | buffer.append(INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()) |
| | | .toString()); |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Random; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.concurrent.atomic.AtomicLong; |
| | | |
| | | import org.glassfish.grizzly.TransportFactory; |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.BindResult; |
| | | import org.opends.sdk.responses.SearchResultEntry; |
| | | |
| | | import com.sun.opends.sdk.util.RecursiveFutureResult; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A load generation tool that can be used to load a Directory Server with Bind |
| | | * requests using one or more LDAP connections. |
| | | */ |
| | | public final class AuthRate extends ConsoleApplication |
| | | { |
| | | private final class BindPerformanceRunner extends PerformanceRunner |
| | | { |
| | | private final class BindStatsThread extends StatsThread |
| | | { |
| | | private final String[] extraColumn; |
| | | |
| | | |
| | | |
| | | private BindStatsThread(final boolean extraFieldRequired) |
| | | { |
| | | super(extraFieldRequired ? new String[] { "bind time %" } |
| | | : new String[0]); |
| | | extraColumn = new String[extraFieldRequired ? 1 : 0]; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | String[] getAdditionalColumns() |
| | | { |
| | | invalidCredRecentCount.set(0); |
| | | if (extraColumn.length != 0) |
| | | { |
| | | final long searchWaitTime = searchWaitRecentTime.getAndSet(0); |
| | | extraColumn[0] = String.format("%.1f", |
| | | ((float) (waitTime - searchWaitTime) / waitTime) * 100.0); |
| | | } |
| | | return extraColumn; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private final class BindUpdateStatsResultHandler extends |
| | | UpdateStatsResultHandler<BindResult> |
| | | { |
| | | private BindUpdateStatsResultHandler(final long startTime, |
| | | final AsynchronousConnection connection, final ConnectionWorker worker) |
| | | { |
| | | super(startTime, connection, worker); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void handleErrorResult(final ErrorResultException error) |
| | | { |
| | | super.handleErrorResult(error); |
| | | |
| | | if (error.getResult().getResultCode() == ResultCode.INVALID_CREDENTIALS) |
| | | { |
| | | invalidCredRecentCount.getAndIncrement(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private final class BindWorkerThread extends ConnectionWorker |
| | | { |
| | | private SearchRequest sr; |
| | | private BindRequest br; |
| | | private Object[] data; |
| | | private final char[] invalidPassword = "invalid-password".toCharArray(); |
| | | |
| | | private final ThreadLocal<Random> rng = new ThreadLocal<Random>() |
| | | { |
| | | |
| | | @Override |
| | | protected Random initialValue() |
| | | { |
| | | return new Random(); |
| | | } |
| | | |
| | | }; |
| | | |
| | | |
| | | |
| | | private BindWorkerThread(final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | super(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public FutureResult<?> performOperation( |
| | | final AsynchronousConnection connection, |
| | | final DataSource[] dataSources, final long startTime) |
| | | { |
| | | if (dataSources != null) |
| | | { |
| | | data = DataSource.generateData(dataSources, data); |
| | | if (data.length == dataSources.length) |
| | | { |
| | | final Object[] newData = new Object[data.length + 1]; |
| | | System.arraycopy(data, 0, newData, 0, data.length); |
| | | data = newData; |
| | | } |
| | | } |
| | | if (filter != null && baseDN != null) |
| | | { |
| | | if (sr == null) |
| | | { |
| | | if (dataSources == null) |
| | | { |
| | | sr = Requests.newSearchRequest(baseDN, scope, filter, attributes); |
| | | } |
| | | else |
| | | { |
| | | sr = Requests.newSearchRequest(String.format(baseDN, data), |
| | | scope, String.format(filter, data), attributes); |
| | | } |
| | | sr.setDereferenceAliasesPolicy(dereferencesAliasesPolicy); |
| | | } |
| | | else if (dataSources != null) |
| | | { |
| | | sr.setFilter(String.format(filter, data)); |
| | | sr.setName(String.format(baseDN, data)); |
| | | } |
| | | |
| | | final RecursiveFutureResult<SearchResultEntry, BindResult> future = |
| | | new RecursiveFutureResult<SearchResultEntry, BindResult>( |
| | | new BindUpdateStatsResultHandler(startTime, connection, this)) |
| | | { |
| | | @Override |
| | | protected FutureResult<? extends BindResult> chainResult( |
| | | final SearchResultEntry innerResult, |
| | | final ResultHandler<? super BindResult> resultHandler) |
| | | throws ErrorResultException |
| | | { |
| | | searchWaitRecentTime.getAndAdd(System.nanoTime() - startTime); |
| | | if (data == null) |
| | | { |
| | | data = new Object[1]; |
| | | } |
| | | data[data.length - 1] = innerResult.getName().toString(); |
| | | return performBind(connection, data, resultHandler); |
| | | } |
| | | }; |
| | | connection.searchSingleEntry(sr, future); |
| | | return future; |
| | | } |
| | | else |
| | | { |
| | | return performBind(connection, data, |
| | | new BindUpdateStatsResultHandler(startTime, connection, this)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private FutureResult<BindResult> performBind( |
| | | final AsynchronousConnection connection, final Object[] data, |
| | | final ResultHandler<? super BindResult> handler) |
| | | { |
| | | final boolean useInvalidPassword; |
| | | |
| | | // Avoid rng if possible. |
| | | switch (invalidCredPercent) |
| | | { |
| | | case 0: |
| | | useInvalidPassword = false; |
| | | break; |
| | | case 100: |
| | | useInvalidPassword = true; |
| | | break; |
| | | default: |
| | | final Random r = rng.get(); |
| | | final int p = r.nextInt(100); |
| | | useInvalidPassword = (p < invalidCredPercent); |
| | | break; |
| | | } |
| | | |
| | | if (bindRequest instanceof SimpleBindRequest) |
| | | { |
| | | final SimpleBindRequest o = (SimpleBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfSimpleBindRequest(o); |
| | | } |
| | | |
| | | final SimpleBindRequest sbr = (SimpleBindRequest) br; |
| | | if (data != null && o.getName() != null) |
| | | { |
| | | sbr.setName(String.format(o.getName(), data)); |
| | | } |
| | | if (useInvalidPassword) |
| | | { |
| | | sbr.setPassword(invalidPassword); |
| | | } |
| | | else |
| | | { |
| | | sbr.setPassword(o.getPassword()); |
| | | } |
| | | } |
| | | else if (bindRequest instanceof DigestMD5SASLBindRequest) |
| | | { |
| | | final DigestMD5SASLBindRequest o = (DigestMD5SASLBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfDigestMD5SASLBindRequest(o); |
| | | } |
| | | |
| | | final DigestMD5SASLBindRequest sbr = (DigestMD5SASLBindRequest) br; |
| | | if (data != null) |
| | | { |
| | | if (o.getAuthenticationID() != null) |
| | | { |
| | | sbr.setAuthenticationID(String.format(o.getAuthenticationID(), |
| | | data)); |
| | | } |
| | | if (o.getAuthorizationID() != null) |
| | | { |
| | | sbr.setAuthorizationID(String.format(o.getAuthorizationID(), data)); |
| | | } |
| | | } |
| | | if (useInvalidPassword) |
| | | { |
| | | sbr.setPassword(invalidPassword); |
| | | } |
| | | else |
| | | { |
| | | sbr.setPassword(o.getPassword()); |
| | | } |
| | | } |
| | | else if (bindRequest instanceof CRAMMD5SASLBindRequest) |
| | | { |
| | | final CRAMMD5SASLBindRequest o = (CRAMMD5SASLBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfCRAMMD5SASLBindRequest(o); |
| | | } |
| | | |
| | | final CRAMMD5SASLBindRequest sbr = (CRAMMD5SASLBindRequest) br; |
| | | if (data != null && o.getAuthenticationID() != null) |
| | | { |
| | | sbr.setAuthenticationID(String.format(o.getAuthenticationID(), data)); |
| | | } |
| | | if (useInvalidPassword) |
| | | { |
| | | sbr.setPassword(invalidPassword); |
| | | } |
| | | else |
| | | { |
| | | sbr.setPassword(o.getPassword()); |
| | | } |
| | | } |
| | | else if (bindRequest instanceof GSSAPISASLBindRequest) |
| | | { |
| | | final GSSAPISASLBindRequest o = (GSSAPISASLBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfGSSAPISASLBindRequest(o); |
| | | } |
| | | |
| | | final GSSAPISASLBindRequest sbr = (GSSAPISASLBindRequest) br; |
| | | if (data != null) |
| | | { |
| | | if (o.getAuthenticationID() != null) |
| | | { |
| | | sbr.setAuthenticationID(String.format(o.getAuthenticationID(), |
| | | data)); |
| | | } |
| | | if (o.getAuthorizationID() != null) |
| | | { |
| | | sbr.setAuthorizationID(String.format(o.getAuthorizationID(), data)); |
| | | } |
| | | } |
| | | if (useInvalidPassword) |
| | | { |
| | | sbr.setPassword(invalidPassword); |
| | | } |
| | | else |
| | | { |
| | | sbr.setPassword(o.getPassword()); |
| | | } |
| | | } |
| | | else if (bindRequest instanceof ExternalSASLBindRequest) |
| | | { |
| | | final ExternalSASLBindRequest o = (ExternalSASLBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfExternalSASLBindRequest(o); |
| | | } |
| | | |
| | | final ExternalSASLBindRequest sbr = (ExternalSASLBindRequest) br; |
| | | if (data != null && o.getAuthorizationID() != null) |
| | | { |
| | | sbr.setAuthorizationID(String.format(o.getAuthorizationID(), data)); |
| | | } |
| | | } |
| | | else if (bindRequest instanceof PlainSASLBindRequest) |
| | | { |
| | | final PlainSASLBindRequest o = (PlainSASLBindRequest) bindRequest; |
| | | if (br == null) |
| | | { |
| | | br = Requests.copyOfPlainSASLBindRequest(o); |
| | | } |
| | | |
| | | final PlainSASLBindRequest sbr = (PlainSASLBindRequest) br; |
| | | if (data != null) |
| | | { |
| | | if (o.getAuthenticationID() != null) |
| | | { |
| | | sbr.setAuthenticationID(String.format(o.getAuthenticationID(), |
| | | data)); |
| | | } |
| | | if (o.getAuthorizationID() != null) |
| | | { |
| | | sbr.setAuthorizationID(String.format(o.getAuthorizationID(), data)); |
| | | } |
| | | } |
| | | if (useInvalidPassword) |
| | | { |
| | | sbr.setPassword(invalidPassword); |
| | | } |
| | | else |
| | | { |
| | | sbr.setPassword(o.getPassword()); |
| | | } |
| | | } |
| | | |
| | | return connection.bind(br, handler); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private final AtomicLong searchWaitRecentTime = new AtomicLong(); |
| | | |
| | | private final AtomicInteger invalidCredRecentCount = new AtomicInteger(); |
| | | |
| | | private String filter; |
| | | |
| | | private String baseDN; |
| | | |
| | | private SearchScope scope; |
| | | |
| | | private DereferenceAliasesPolicy dereferencesAliasesPolicy; |
| | | |
| | | private String[] attributes; |
| | | |
| | | private BindRequest bindRequest; |
| | | |
| | | private int invalidCredPercent; |
| | | |
| | | |
| | | |
| | | private BindPerformanceRunner(final ArgumentParser argParser, |
| | | final ConsoleApplication app) throws ArgumentException |
| | | { |
| | | super(argParser, app, true, true, true); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | ConnectionWorker newConnectionWorker( |
| | | final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | return new BindWorkerThread(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | StatsThread newStatsThread() |
| | | { |
| | | return new BindStatsThread(filter != null && baseDN != null); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The main method for AuthRate tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainAuthRate(args, System.in, System.out, System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainAuthRate(final String[] args) |
| | | { |
| | | return mainAuthRate(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainAuthRate(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | |
| | | { |
| | | return new AuthRate(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | private BooleanArgument scriptFriendly; |
| | | |
| | | |
| | | |
| | | private AuthRate(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return scriptFriendly.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_AUTHRATE_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser( |
| | | AuthRate.class.getName(), toolDescription, false, true, 0, 0, |
| | | "[filter format string] [attributes ...]"); |
| | | |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | BindPerformanceRunner runner; |
| | | |
| | | StringArgument baseDN; |
| | | MultiChoiceArgument<SearchScope> searchScope; |
| | | MultiChoiceArgument<DereferenceAliasesPolicy> dereferencePolicy; |
| | | BooleanArgument showUsage; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | IntegerArgument invalidCredPercent; |
| | | |
| | | try |
| | | { |
| | | TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory()); |
| | | connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this); |
| | | runner = new BindPerformanceRunner(argParser, this); |
| | | |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | |
| | | baseDN = new StringArgument("baseDN", OPTION_SHORT_BASEDN, |
| | | OPTION_LONG_BASEDN, false, false, true, |
| | | INFO_BASEDN_PLACEHOLDER.get(), null, null, |
| | | INFO_SEARCHRATE_TOOL_DESCRIPTION_BASEDN.get()); |
| | | baseDN.setPropertyName(OPTION_LONG_BASEDN); |
| | | argParser.addArgument(baseDN); |
| | | |
| | | searchScope = new MultiChoiceArgument<SearchScope>("searchScope", 's', |
| | | "searchScope", false, true, INFO_SEARCH_SCOPE_PLACEHOLDER.get(), |
| | | SearchScope.values(), false, |
| | | INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE.get()); |
| | | searchScope.setPropertyName("searchScope"); |
| | | searchScope.setDefaultValue(SearchScope.WHOLE_SUBTREE); |
| | | argParser.addArgument(searchScope); |
| | | |
| | | dereferencePolicy = new MultiChoiceArgument<DereferenceAliasesPolicy>( |
| | | "derefpolicy", 'a', "dereferencePolicy", false, true, |
| | | INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(), |
| | | DereferenceAliasesPolicy.values(), false, |
| | | INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY.get()); |
| | | dereferencePolicy.setPropertyName("dereferencePolicy"); |
| | | dereferencePolicy.setDefaultValue(DereferenceAliasesPolicy.NEVER); |
| | | argParser.addArgument(dereferencePolicy); |
| | | |
| | | invalidCredPercent = new IntegerArgument("invalidPassword", 'I', |
| | | "invalidPassword", false, false, true, |
| | | LocalizableMessage.raw("{invalidPassword}"), 0, null, true, 0, true, |
| | | 100, |
| | | LocalizableMessage.raw("Percent of bind operations with simulated " |
| | | + "invalid password")); |
| | | invalidCredPercent.setPropertyName("invalidPassword"); |
| | | argParser.addArgument(invalidCredPercent); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | scriptFriendly = new BooleanArgument("scriptFriendly", 'S', |
| | | "scriptFriendly", INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()); |
| | | scriptFriendly.setPropertyName("scriptFriendly"); |
| | | argParser.addArgument(scriptFriendly); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = connectionFactoryProvider.getConnectionFactory(); |
| | | runner.validate(); |
| | | |
| | | runner.bindRequest = connectionFactoryProvider.getBindRequest(); |
| | | if (runner.bindRequest == null) |
| | | { |
| | | throw new ArgumentException( |
| | | LocalizableMessage |
| | | .raw("Authentication information must be provided to use this tool")); |
| | | } |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final List<String> attributes = new LinkedList<String>(); |
| | | final ArrayList<String> filterAndAttributeStrings = argParser |
| | | .getTrailingArguments(); |
| | | if (filterAndAttributeStrings.size() > 0) |
| | | { |
| | | // the list of trailing arguments should be structured as follow: |
| | | // the first trailing argument is considered the filter, the other as |
| | | // attributes. |
| | | runner.filter = filterAndAttributeStrings.remove(0); |
| | | |
| | | // The rest are attributes |
| | | for (final String s : filterAndAttributeStrings) |
| | | { |
| | | attributes.add(s); |
| | | } |
| | | } |
| | | runner.attributes = attributes.toArray(new String[attributes.size()]); |
| | | runner.baseDN = baseDN.getValue(); |
| | | try |
| | | { |
| | | runner.scope = searchScope.getTypedValue(); |
| | | runner.dereferencesAliasesPolicy = dereferencePolicy.getTypedValue(); |
| | | runner.invalidCredPercent = invalidCredPercent.getIntValue(); |
| | | } |
| | | catch (final ArgumentException ex1) |
| | | { |
| | | println(ex1.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Try it out to make sure the format string and data sources |
| | | // match. |
| | | final Object[] data = DataSource |
| | | .generateData(runner.getDataSources(), null); |
| | | try |
| | | { |
| | | if (runner.baseDN != null && runner.filter != null) |
| | | { |
| | | String.format(runner.filter, data); |
| | | String.format(runner.baseDN, data); |
| | | } |
| | | } |
| | | catch (final Exception ex1) |
| | | { |
| | | println(LocalizableMessage.raw("Error formatting filter or base DN: " |
| | | + ex1.toString())); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | return runner.run(connectionFactory); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.BindRequest; |
| | | import org.opends.sdk.responses.BindResult; |
| | | |
| | | import com.sun.opends.sdk.util.AsynchronousConnectionDecorator; |
| | | import com.sun.opends.sdk.util.FutureResultTransformer; |
| | | import com.sun.opends.sdk.util.RecursiveFutureResult; |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * An authenticated connection factory can be used to create pre-authenticated |
| | | * connections to a Directory Server. |
| | | * <p> |
| | | * The connections returned by an authenticated connection factory support all |
| | | * operations with the exception of Bind requests. Attempts to perform a Bind |
| | | * will result in an {@code UnsupportedOperationException}. |
| | | * <p> |
| | | * In addition, the returned connections support retrieval of the |
| | | * {@code BindResult} returned from the initial Bind request, or last rebind. |
| | | * <p> |
| | | * Support for connection re-authentication is provided through the |
| | | * {@link #setRebindAllowed} method which, if set to {@code true}, causes |
| | | * subsequent connections created using the factory to support the |
| | | * {@code rebind} method. |
| | | * <p> |
| | | * If the Bind request fails for some reason (e.g. invalid credentials), then |
| | | * the connection attempt will fail and an {@code ErrorResultException} will be |
| | | * thrown. |
| | | */ |
| | | final class AuthenticatedConnectionFactory extends AbstractConnectionFactory |
| | | implements ConnectionFactory |
| | | { |
| | | |
| | | /** |
| | | * An authenticated asynchronous connection supports all operations except |
| | | * Bind operations. |
| | | */ |
| | | public static final class AuthenticatedAsynchronousConnection extends |
| | | AsynchronousConnectionDecorator |
| | | { |
| | | |
| | | private final BindRequest request; |
| | | |
| | | private volatile BindResult result; |
| | | |
| | | |
| | | |
| | | private AuthenticatedAsynchronousConnection( |
| | | final AsynchronousConnection connection, final BindRequest request, |
| | | final BindResult result) |
| | | { |
| | | super(connection); |
| | | this.request = request; |
| | | this.result = result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns an unmodifiable view of the Bind result which was returned from |
| | | * the server after authentication. |
| | | * |
| | | * @return The Bind result which was returned from the server after |
| | | * authentication. |
| | | */ |
| | | public BindResult getAuthenticatedBindResult() |
| | | { |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Re-authenticates to the Directory Server using the bind request |
| | | * associated with this connection. If re-authentication fails for some |
| | | * reason then this connection will be automatically closed. |
| | | * |
| | | * @param handler |
| | | * A result handler which can be used to asynchronously process the |
| | | * operation result when it is received, may be {@code null}. |
| | | * @return A future representing the result of the operation. |
| | | * @throws UnsupportedOperationException |
| | | * If this connection does not support rebind operations. |
| | | * @throws IllegalStateException |
| | | * If this connection has already been closed, i.e. if |
| | | * {@code isClosed() == true}. |
| | | */ |
| | | public FutureResult<BindResult> rebind( |
| | | final ResultHandler<? super BindResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | if (request == null) |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | // Wrap the client handler so that we can update the connection |
| | | // state. |
| | | final ResultHandler<? super BindResult> clientHandler = handler; |
| | | |
| | | final ResultHandler<BindResult> handlerWrapper = new ResultHandler<BindResult>() |
| | | { |
| | | |
| | | public void handleErrorResult(final ErrorResultException error) |
| | | { |
| | | // This connection is now unauthenticated so prevent |
| | | // further use. |
| | | connection.close(); |
| | | |
| | | if (clientHandler != null) |
| | | { |
| | | clientHandler.handleErrorResult(error); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleResult(final BindResult result) |
| | | { |
| | | // Save the result. |
| | | AuthenticatedAsynchronousConnection.this.result = result; |
| | | |
| | | if (clientHandler != null) |
| | | { |
| | | clientHandler.handleResult(result); |
| | | } |
| | | } |
| | | |
| | | }; |
| | | |
| | | return connection.bind(request, handlerWrapper); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String toString() |
| | | { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("AuthenticatedConnection("); |
| | | builder.append(connection); |
| | | builder.append(')'); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * An authenticated synchronous connection supports all operations except Bind |
| | | * operations. |
| | | */ |
| | | public static final class AuthenticatedConnection extends |
| | | SynchronousConnection |
| | | { |
| | | private final AuthenticatedAsynchronousConnection connection; |
| | | |
| | | |
| | | |
| | | private AuthenticatedConnection( |
| | | final AuthenticatedAsynchronousConnection connection) |
| | | { |
| | | super(connection); |
| | | this.connection = connection; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | @Override |
| | | public BindResult bind(final BindRequest request) |
| | | throws UnsupportedOperationException |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | @Override |
| | | public BindResult bind(final String name, final char[] password) |
| | | throws UnsupportedOperationException |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns an unmodifiable view of the Bind result which was returned from |
| | | * the server after authentication. |
| | | * |
| | | * @return The Bind result which was returned from the server after |
| | | * authentication. |
| | | */ |
| | | public BindResult getAuthenticatedBindResult() |
| | | { |
| | | return connection.getAuthenticatedBindResult(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Re-authenticates to the Directory Server using the bind request |
| | | * associated with this connection. If re-authentication fails for some |
| | | * reason then this connection will be automatically closed. |
| | | * |
| | | * @return The result of the operation. |
| | | * @throws ErrorResultException |
| | | * If the result code indicates that the request failed for some |
| | | * reason. |
| | | * @throws InterruptedException |
| | | * If the current thread was interrupted while waiting. |
| | | * @throws UnsupportedOperationException |
| | | * If this connection does not support rebind operations. |
| | | * @throws IllegalStateException |
| | | * If this connection has already been closed, i.e. if |
| | | * {@code isClosed() == true}. |
| | | */ |
| | | public BindResult rebind() throws ErrorResultException, |
| | | InterruptedException, UnsupportedOperationException, |
| | | IllegalStateException |
| | | { |
| | | |
| | | if (connection.request == null) |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | return super.bind(connection.request); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class FutureResultImpl |
| | | { |
| | | private final FutureResultTransformer<BindResult, AsynchronousConnection> futureBindResult; |
| | | |
| | | private final RecursiveFutureResult<AsynchronousConnection, BindResult> futureConnectionResult; |
| | | |
| | | private final BindRequest bindRequest; |
| | | |
| | | private AsynchronousConnection connection; |
| | | |
| | | |
| | | |
| | | private FutureResultImpl(final BindRequest request, |
| | | final ResultHandler<? super AsynchronousConnection> handler) |
| | | { |
| | | this.bindRequest = request; |
| | | this.futureBindResult = new FutureResultTransformer<BindResult, AsynchronousConnection>( |
| | | handler) |
| | | { |
| | | |
| | | @Override |
| | | protected ErrorResultException transformErrorResult( |
| | | final ErrorResultException errorResult) |
| | | { |
| | | // Ensure that the connection is closed. |
| | | try |
| | | { |
| | | connection.close(); |
| | | connection = null; |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | // Ignore. |
| | | } |
| | | return errorResult; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | protected AuthenticatedAsynchronousConnection transformResult( |
| | | final BindResult result) throws ErrorResultException |
| | | { |
| | | // FIXME: should make the result unmodifiable. |
| | | return new AuthenticatedAsynchronousConnection(connection, |
| | | bindRequest, result); |
| | | } |
| | | |
| | | }; |
| | | this.futureConnectionResult = new RecursiveFutureResult<AsynchronousConnection, BindResult>( |
| | | futureBindResult) |
| | | { |
| | | |
| | | @Override |
| | | protected FutureResult<? extends BindResult> chainResult( |
| | | final AsynchronousConnection innerResult, |
| | | final ResultHandler<? super BindResult> handler) |
| | | throws ErrorResultException |
| | | { |
| | | connection = innerResult; |
| | | return connection.bind(bindRequest, handler); |
| | | } |
| | | }; |
| | | futureBindResult.setFutureResult(futureConnectionResult); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | private final BindRequest request; |
| | | |
| | | private final ConnectionFactory parentFactory; |
| | | |
| | | private boolean allowRebinds = false; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new authenticated connection factory which will obtain |
| | | * connections using the provided connection factory and immediately perform |
| | | * the provided Bind request. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for connecting to the Directory |
| | | * Server. |
| | | * @param request |
| | | * The Bind request to use for authentication. |
| | | * @throws NullPointerException |
| | | * If {@code factory} or {@code request} was {@code null}. |
| | | */ |
| | | public AuthenticatedConnectionFactory(final ConnectionFactory factory, |
| | | final BindRequest request) throws NullPointerException |
| | | { |
| | | Validator.ensureNotNull(factory, request); |
| | | this.parentFactory = factory; |
| | | |
| | | // FIXME: should do a defensive copy. |
| | | this.request = request; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public FutureResult<AsynchronousConnection> getAsynchronousConnection( |
| | | final ResultHandler<? super AsynchronousConnection> handler) |
| | | { |
| | | final FutureResultImpl future = new FutureResultImpl(request, handler); |
| | | future.futureConnectionResult.setFutureResult(parentFactory |
| | | .getAsynchronousConnection(future.futureConnectionResult)); |
| | | return future.futureBindResult; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not rebind requests are to be supported by connections |
| | | * created by this authenticated connection factory. |
| | | * <p> |
| | | * Rebind requests are invoked using the connection's {@code rebind} method |
| | | * which will throw an {@code UnsupportedOperationException} if rebinds are |
| | | * not supported (the default). |
| | | * |
| | | * @return allowRebinds {@code true} if the {@code rebind} operation is to be |
| | | * supported, otherwise {@code false}. |
| | | */ |
| | | public boolean isRebindAllowed() |
| | | { |
| | | return allowRebinds; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether or not rebind requests are to be supported by connections |
| | | * created by this authenticated connection factory. |
| | | * <p> |
| | | * Rebind requests are invoked using the connection's {@code rebind} method |
| | | * which will throw an {@code UnsupportedOperationException} if rebinds are |
| | | * not supported (the default). |
| | | * |
| | | * @param allowRebinds |
| | | * {@code true} if the {@code rebind} operation is to be supported, |
| | | * otherwise {@code false}. |
| | | * @return A reference to this connection factory. |
| | | */ |
| | | public AuthenticatedConnectionFactory setRebindAllowed( |
| | | final boolean allowRebinds) |
| | | { |
| | | this.allowRebinds = allowRebinds; |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("AuthenticatedConnectionFactory("); |
| | | builder.append(String.valueOf(parentFactory)); |
| | | builder.append(')'); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_BOOLEANARG_NO_VALUE_ALLOWED; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an argument type that will be used to represent Boolean |
| | | * values. These arguments will never take values from the command line but and |
| | | * will never be required. If the argument is provided, then it will be |
| | | * considered true, and if not then it will be considered false. As such, the |
| | | * default value will always be "false". |
| | | */ |
| | | final class BooleanArgument extends Argument |
| | | { |
| | | /** |
| | | * Creates a new Boolean argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public BooleanArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, false, false, false, null, |
| | | String.valueOf(false), null, description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | final public void addValue(final String valueString) |
| | | { |
| | | if (valueString != null) |
| | | { |
| | | clearValues(); |
| | | super.addValue(valueString); |
| | | super.setPresent(Boolean.valueOf(valueString)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | final public void setPresent(final boolean isPresent) |
| | | { |
| | | addValue(String.valueOf(isPresent)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | @Override |
| | | public boolean valueIsAcceptable(final String valueString, |
| | | final LocalizableMessageBuilder invalidReason) |
| | | { |
| | | // This argument type should never have a value, so any value |
| | | // provided will |
| | | // be unacceptable. |
| | | |
| | | invalidReason.append(ERR_BOOLEANARG_NO_VALUE_ALLOWED.get(getName())); |
| | | |
| | | return false; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.LocalizableException; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | |
| | | import com.sun.opends.sdk.messages.Messages; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Thrown to indicate that a problem occurred when interacting with the client. |
| | | * For example, if input provided by the client was invalid. |
| | | */ |
| | | @SuppressWarnings("serial") |
| | | final class CLIException extends Exception implements LocalizableException |
| | | { |
| | | |
| | | /** |
| | | * Adapts any exception that may have occurred whilst reading input from the |
| | | * console. |
| | | * |
| | | * @param cause |
| | | * The exception that occurred whilst reading input from the console. |
| | | * @return Returns a new CLI exception describing a problem that occurred |
| | | * whilst reading input from the console. |
| | | */ |
| | | static CLIException adaptInputException(final Throwable cause) |
| | | { |
| | | return new CLIException(Messages.ERR_CONSOLE_INPUT_ERROR.get(cause |
| | | .getMessage()), cause); |
| | | } |
| | | |
| | | |
| | | |
| | | private final LocalizableMessage message; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new CLI exception with the provided message. |
| | | * |
| | | * @param message |
| | | * The message explaining the problem that occurred. |
| | | */ |
| | | CLIException(final LocalizableMessage message) |
| | | { |
| | | super(message.toString()); |
| | | this.message = message; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new CLI exception with the provided message and cause. |
| | | * |
| | | * @param message |
| | | * The message explaining the problem that occurred. |
| | | * @param cause |
| | | * The cause of this exception. |
| | | */ |
| | | CLIException(final LocalizableMessage message, final Throwable cause) |
| | | { |
| | | super(message.toString(), cause); |
| | | this.message = message; |
| | | } |
| | | |
| | | |
| | | |
| | | public LocalizableMessage getMessageObject() |
| | | { |
| | | return message; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.net.InetAddress; |
| | | import java.security.GeneralSecurityException; |
| | | import java.security.KeyStore; |
| | | import java.security.KeyStoreException; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.cert.CertificateException; |
| | | import java.util.logging.Logger; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.TrustManager; |
| | | import javax.net.ssl.X509KeyManager; |
| | | import javax.net.ssl.X509TrustManager; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A connection factory designed for use with command line tools. |
| | | */ |
| | | final class ConnectionFactoryProvider |
| | | { |
| | | /** |
| | | * End Of Line. |
| | | */ |
| | | static final String EOL = System.getProperty("line.separator"); |
| | | |
| | | /** |
| | | * The Logger. |
| | | */ |
| | | static final Logger LOG = Logger |
| | | .getLogger(ConnectionFactoryProvider.class.getName()); |
| | | |
| | | /** |
| | | * The 'hostName' global argument. |
| | | */ |
| | | private StringArgument hostNameArg = null; |
| | | |
| | | /** |
| | | * The 'port' global argument. |
| | | */ |
| | | private IntegerArgument portArg = null; |
| | | |
| | | /** |
| | | * The 'bindDN' global argument. |
| | | */ |
| | | private StringArgument bindNameArg = null; |
| | | |
| | | /** |
| | | * The 'bindPasswordFile' global argument. |
| | | */ |
| | | private FileBasedArgument bindPasswordFileArg = null; |
| | | |
| | | /** |
| | | * The 'bindPassword' global argument. |
| | | */ |
| | | private StringArgument bindPasswordArg = null; |
| | | |
| | | /** |
| | | * The 'trustAllArg' global argument. |
| | | */ |
| | | private BooleanArgument trustAllArg = null; |
| | | |
| | | /** |
| | | * The 'trustStore' global argument. |
| | | */ |
| | | private StringArgument trustStorePathArg = null; |
| | | |
| | | /** |
| | | * The 'trustStorePassword' global argument. |
| | | */ |
| | | private StringArgument trustStorePasswordArg = null; |
| | | |
| | | /** |
| | | * The 'trustStorePasswordFile' global argument. |
| | | */ |
| | | private FileBasedArgument trustStorePasswordFileArg = null; |
| | | |
| | | /** |
| | | * The 'keyStore' global argument. |
| | | */ |
| | | private StringArgument keyStorePathArg = null; |
| | | |
| | | /** |
| | | * The 'keyStorePassword' global argument. |
| | | */ |
| | | private StringArgument keyStorePasswordArg = null; |
| | | |
| | | /** |
| | | * The 'keyStorePasswordFile' global argument. |
| | | */ |
| | | private FileBasedArgument keyStorePasswordFileArg = null; |
| | | |
| | | /** |
| | | * The 'certNicknameArg' global argument. |
| | | */ |
| | | private StringArgument certNicknameArg = null; |
| | | |
| | | /** |
| | | * The 'useSSLArg' global argument. |
| | | */ |
| | | private BooleanArgument useSSLArg = null; |
| | | |
| | | /** |
| | | * The 'useStartTLSArg' global argument. |
| | | */ |
| | | private BooleanArgument useStartTLSArg = null; |
| | | |
| | | /** |
| | | * Argument indicating a SASL option. |
| | | */ |
| | | private StringArgument saslOptionArg = null; |
| | | |
| | | /** |
| | | * Whether to request that the server return the authorization ID in the bind |
| | | * response. |
| | | */ |
| | | private final BooleanArgument reportAuthzID; |
| | | |
| | | /** |
| | | * Whether to use the password policy control in the bind request. |
| | | */ |
| | | private final BooleanArgument usePasswordPolicyControl; |
| | | |
| | | private int port = 389; |
| | | |
| | | private SSLContext sslContext; |
| | | |
| | | private ConnectionFactory connFactory; |
| | | |
| | | private ConnectionFactory authenticatedConnFactory; |
| | | |
| | | private BindRequest bindRequest = null; |
| | | |
| | | private final ConsoleApplication app; |
| | | |
| | | |
| | | |
| | | public ConnectionFactoryProvider(final ArgumentParser argumentParser, |
| | | final ConsoleApplication app) throws ArgumentException |
| | | { |
| | | this(argumentParser, app, "cn=Directory Manager", 389, false); |
| | | } |
| | | |
| | | |
| | | |
| | | public ConnectionFactoryProvider(final ArgumentParser argumentParser, |
| | | final ConsoleApplication app, final String defaultBindDN, |
| | | final int defaultPort, final boolean alwaysSSL) throws ArgumentException |
| | | { |
| | | this.app = app; |
| | | useSSLArg = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL, |
| | | OPTION_LONG_USE_SSL, INFO_DESCRIPTION_USE_SSL.get()); |
| | | useSSLArg.setPropertyName(OPTION_LONG_USE_SSL); |
| | | if (!alwaysSSL) |
| | | { |
| | | argumentParser.addLdapConnectionArgument(useSSLArg); |
| | | } |
| | | else |
| | | { |
| | | // simulate that the useSSL arg has been given in the CLI |
| | | useSSLArg.setPresent(true); |
| | | } |
| | | |
| | | useStartTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS, |
| | | OPTION_LONG_START_TLS, INFO_DESCRIPTION_START_TLS.get()); |
| | | useStartTLSArg.setPropertyName(OPTION_LONG_START_TLS); |
| | | if (!alwaysSSL) |
| | | { |
| | | argumentParser.addLdapConnectionArgument(useStartTLSArg); |
| | | } |
| | | |
| | | String defaultHostName; |
| | | try |
| | | { |
| | | defaultHostName = InetAddress.getLocalHost().getHostName(); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | defaultHostName = "Unknown (" + e + ")"; |
| | | } |
| | | hostNameArg = new StringArgument("host", OPTION_SHORT_HOST, |
| | | OPTION_LONG_HOST, false, false, true, INFO_HOST_PLACEHOLDER.get(), |
| | | defaultHostName, null, INFO_DESCRIPTION_HOST.get()); |
| | | hostNameArg.setPropertyName(OPTION_LONG_HOST); |
| | | argumentParser.addLdapConnectionArgument(hostNameArg); |
| | | |
| | | LocalizableMessage portDescription = INFO_DESCRIPTION_PORT.get(); |
| | | if (alwaysSSL) |
| | | { |
| | | portDescription = INFO_DESCRIPTION_ADMIN_PORT.get(); |
| | | } |
| | | |
| | | portArg = new IntegerArgument("port", OPTION_SHORT_PORT, OPTION_LONG_PORT, |
| | | false, false, true, INFO_PORT_PLACEHOLDER.get(), defaultPort, null, |
| | | portDescription); |
| | | portArg.setPropertyName(OPTION_LONG_PORT); |
| | | argumentParser.addLdapConnectionArgument(portArg); |
| | | |
| | | bindNameArg = new StringArgument("bindDN", OPTION_SHORT_BINDDN, |
| | | OPTION_LONG_BINDDN, false, false, true, INFO_BINDDN_PLACEHOLDER.get(), |
| | | defaultBindDN, null, INFO_DESCRIPTION_BINDDN.get()); |
| | | bindNameArg.setPropertyName(OPTION_LONG_BINDDN); |
| | | argumentParser.addLdapConnectionArgument(bindNameArg); |
| | | |
| | | bindPasswordArg = new StringArgument("bindPassword", OPTION_SHORT_BINDPWD, |
| | | OPTION_LONG_BINDPWD, false, false, true, |
| | | INFO_BINDPWD_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_BINDPASSWORD.get()); |
| | | bindPasswordArg.setPropertyName(OPTION_LONG_BINDPWD); |
| | | argumentParser.addLdapConnectionArgument(bindPasswordArg); |
| | | |
| | | bindPasswordFileArg = new FileBasedArgument("bindPasswordFile", |
| | | OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_BINDPWD_FILE, false, false, |
| | | INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_BINDPASSWORDFILE.get()); |
| | | bindPasswordFileArg.setPropertyName(OPTION_LONG_BINDPWD_FILE); |
| | | argumentParser.addLdapConnectionArgument(bindPasswordFileArg); |
| | | |
| | | saslOptionArg = new StringArgument("sasloption", OPTION_SHORT_SASLOPTION, |
| | | OPTION_LONG_SASLOPTION, false, true, true, INFO_SASL_OPTION_PLACEHOLDER |
| | | .get(), null, null, INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS.get()); |
| | | saslOptionArg.setPropertyName(OPTION_LONG_SASLOPTION); |
| | | argumentParser.addLdapConnectionArgument(saslOptionArg); |
| | | |
| | | trustAllArg = new BooleanArgument("trustAll", OPTION_SHORT_TRUSTALL, |
| | | OPTION_LONG_TRUSTALL, INFO_DESCRIPTION_TRUSTALL.get()); |
| | | trustAllArg.setPropertyName(OPTION_LONG_TRUSTALL); |
| | | argumentParser.addLdapConnectionArgument(trustAllArg); |
| | | |
| | | trustStorePathArg = new StringArgument("trustStorePath", |
| | | OPTION_SHORT_TRUSTSTOREPATH, OPTION_LONG_TRUSTSTOREPATH, false, false, |
| | | true, INFO_TRUSTSTOREPATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_TRUSTSTOREPATH.get()); |
| | | trustStorePathArg.setPropertyName(OPTION_LONG_TRUSTSTOREPATH); |
| | | argumentParser.addLdapConnectionArgument(trustStorePathArg); |
| | | |
| | | trustStorePasswordArg = new StringArgument("trustStorePassword", |
| | | OPTION_SHORT_TRUSTSTORE_PWD, OPTION_LONG_TRUSTSTORE_PWD, false, false, |
| | | true, INFO_TRUSTSTORE_PWD_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_TRUSTSTOREPASSWORD.get()); |
| | | trustStorePasswordArg.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD); |
| | | argumentParser.addLdapConnectionArgument(trustStorePasswordArg); |
| | | |
| | | trustStorePasswordFileArg = new FileBasedArgument("trustStorePasswordFile", |
| | | OPTION_SHORT_TRUSTSTORE_PWD_FILE, OPTION_LONG_TRUSTSTORE_PWD_FILE, |
| | | false, false, INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE.get()); |
| | | trustStorePasswordFileArg.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD_FILE); |
| | | argumentParser.addLdapConnectionArgument(trustStorePasswordFileArg); |
| | | |
| | | keyStorePathArg = new StringArgument("keyStorePath", |
| | | OPTION_SHORT_KEYSTOREPATH, OPTION_LONG_KEYSTOREPATH, false, false, |
| | | true, INFO_KEYSTOREPATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_KEYSTOREPATH.get()); |
| | | keyStorePathArg.setPropertyName(OPTION_LONG_KEYSTOREPATH); |
| | | argumentParser.addLdapConnectionArgument(keyStorePathArg); |
| | | |
| | | keyStorePasswordArg = new StringArgument("keyStorePassword", |
| | | OPTION_SHORT_KEYSTORE_PWD, OPTION_LONG_KEYSTORE_PWD, false, false, |
| | | true, INFO_KEYSTORE_PWD_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_KEYSTOREPASSWORD.get()); |
| | | keyStorePasswordArg.setPropertyName(OPTION_LONG_KEYSTORE_PWD); |
| | | argumentParser.addLdapConnectionArgument(keyStorePasswordArg); |
| | | |
| | | keyStorePasswordFileArg = new FileBasedArgument("keystorePasswordFile", |
| | | OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false, |
| | | false, INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE.get()); |
| | | keyStorePasswordFileArg.setPropertyName(OPTION_LONG_KEYSTORE_PWD_FILE); |
| | | argumentParser.addLdapConnectionArgument(keyStorePasswordFileArg); |
| | | |
| | | certNicknameArg = new StringArgument("certNickname", |
| | | OPTION_SHORT_CERT_NICKNAME, OPTION_LONG_CERT_NICKNAME, false, false, |
| | | true, INFO_NICKNAME_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_CERT_NICKNAME.get()); |
| | | certNicknameArg.setPropertyName(OPTION_LONG_CERT_NICKNAME); |
| | | argumentParser.addLdapConnectionArgument(certNicknameArg); |
| | | |
| | | reportAuthzID = new BooleanArgument("reportauthzid", 'E', |
| | | OPTION_LONG_REPORT_AUTHZ_ID, INFO_DESCRIPTION_REPORT_AUTHZID.get()); |
| | | reportAuthzID.setPropertyName(OPTION_LONG_REPORT_AUTHZ_ID); |
| | | argumentParser.addArgument(reportAuthzID); |
| | | |
| | | usePasswordPolicyControl = new BooleanArgument("usepwpolicycontrol", null, |
| | | OPTION_LONG_USE_PW_POLICY_CTL, INFO_DESCRIPTION_USE_PWP_CONTROL.get()); |
| | | usePasswordPolicyControl.setPropertyName(OPTION_LONG_USE_PW_POLICY_CTL); |
| | | argumentParser.addArgument(usePasswordPolicyControl); |
| | | } |
| | | |
| | | |
| | | public ConnectionFactory getConnectionFactory() throws ArgumentException |
| | | { |
| | | if(connFactory == null) |
| | | { |
| | | port = portArg.getIntValue(); |
| | | |
| | | // Couldn't have at the same time bindPassword and bindPasswordFile |
| | | if (bindPasswordArg.isPresent() && bindPasswordFileArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | bindPasswordArg.getLongIdentifier(), bindPasswordFileArg |
| | | .getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | // Couldn't have at the same time trustAll and |
| | | // trustStore related arg |
| | | if (trustAllArg.isPresent() && trustStorePathArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | trustAllArg.getLongIdentifier(), trustStorePathArg |
| | | .getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | if (trustAllArg.isPresent() && trustStorePasswordArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | trustAllArg.getLongIdentifier(), trustStorePasswordArg |
| | | .getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | if (trustAllArg.isPresent() && trustStorePasswordFileArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | trustAllArg.getLongIdentifier(), trustStorePasswordFileArg |
| | | .getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | // Couldn't have at the same time trustStorePasswordArg and |
| | | // trustStorePasswordFileArg |
| | | if (trustStorePasswordArg.isPresent() |
| | | && trustStorePasswordFileArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | trustStorePasswordArg.getLongIdentifier(), trustStorePasswordFileArg |
| | | .getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (trustStorePathArg.isPresent()) |
| | | { |
| | | // Check that the path exists and is readable |
| | | final String value = trustStorePathArg.getValue(); |
| | | if (!canRead(trustStorePathArg.getValue())) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_READ_TRUSTSTORE |
| | | .get(value); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | if (keyStorePathArg.isPresent()) |
| | | { |
| | | // Check that the path exists and is readable |
| | | final String value = keyStorePathArg.getValue(); |
| | | if (!canRead(trustStorePathArg.getValue())) |
| | | { |
| | | final LocalizableMessage message = |
| | | ERR_CANNOT_READ_KEYSTORE.get(value); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | // Couldn't have at the same time startTLSArg and |
| | | // useSSLArg |
| | | if (useStartTLSArg.isPresent() && useSSLArg.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | useStartTLSArg.getLongIdentifier(), useSSLArg.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | try |
| | | { |
| | | if (useSSLArg.isPresent() || useStartTLSArg.isPresent()) |
| | | { |
| | | String clientAlias; |
| | | if (certNicknameArg.isPresent()) |
| | | { |
| | | clientAlias = certNicknameArg.getValue(); |
| | | } |
| | | else |
| | | { |
| | | clientAlias = null; |
| | | } |
| | | |
| | | if (sslContext == null) |
| | | { |
| | | final TrustManager trustManager = getTrustManager(); |
| | | |
| | | X509KeyManager keyManager = null; |
| | | final X509KeyManager akm = |
| | | getKeyManager(keyStorePathArg.getValue()); |
| | | |
| | | if (akm != null && clientAlias != null) |
| | | { |
| | | keyManager = KeyManagers.useSingleCertificate(clientAlias, akm); |
| | | } |
| | | |
| | | sslContext = new SSLContextBuilder().setTrustManager(trustManager) |
| | | .setKeyManager(keyManager).getSSLContext(); |
| | | } |
| | | } |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | throw new ArgumentException(ERR_LDAP_CONN_CANNOT_INITIALIZE_SSL.get(e |
| | | .toString()), e); |
| | | } |
| | | |
| | | if (sslContext != null) |
| | | { |
| | | final LDAPOptions options = new LDAPOptions().setSSLContext(sslContext) |
| | | .setUseStartTLS(useStartTLSArg.isPresent()); |
| | | connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), port, |
| | | options); |
| | | } |
| | | else |
| | | { |
| | | connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), port); |
| | | } |
| | | } |
| | | return connFactory; |
| | | } |
| | | |
| | | public ConnectionFactory getAuthenticatedConnectionFactory() |
| | | throws ArgumentException |
| | | { |
| | | if(authenticatedConnFactory == null) |
| | | { |
| | | authenticatedConnFactory = getConnectionFactory(); |
| | | BindRequest bindRequest = getBindRequest(); |
| | | if(bindRequest != null) |
| | | { |
| | | authenticatedConnFactory = |
| | | Connections.newAuthenticatedConnectionFactory( |
| | | authenticatedConnFactory, bindRequest); |
| | | } |
| | | } |
| | | return authenticatedConnFactory; |
| | | } |
| | | |
| | | /** |
| | | * Returns <CODE>true</CODE> if we can read on the provided path and |
| | | * <CODE>false</CODE> otherwise. |
| | | * |
| | | * @param path |
| | | * the path. |
| | | * @return <CODE>true</CODE> if we can read on the provided path and |
| | | * <CODE>false</CODE> otherwise. |
| | | */ |
| | | private boolean canRead(final String path) |
| | | { |
| | | boolean canRead; |
| | | final File file = new File(path); |
| | | canRead = file.exists() && file.canRead(); |
| | | return canRead; |
| | | } |
| | | |
| | | |
| | | |
| | | private String getAuthID(final String mech) throws ArgumentException |
| | | { |
| | | String value = null; |
| | | for (final String s : saslOptionArg.getValues()) |
| | | { |
| | | if (s.startsWith(SASL_PROPERTY_AUTHID)) |
| | | { |
| | | value = parseSASLOptionValue(s); |
| | | break; |
| | | } |
| | | } |
| | | if (value == null && bindNameArg.isPresent()) |
| | | { |
| | | value = "dn: " + bindNameArg.getValue(); |
| | | } |
| | | if (value == null && app.isInteractive()) |
| | | { |
| | | try { |
| | | value = app.readInput(LocalizableMessage.raw("Authentication ID:"), |
| | | bindNameArg.getDefaultValue() == null ? null : "dn: " |
| | | + bindNameArg.getDefaultValue()); |
| | | } catch (CLIException e) { |
| | | throw new ArgumentException( |
| | | LocalizableMessage.raw("Unable to read authentication ID"), e); |
| | | } |
| | | } |
| | | if (value == null) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPAUTH_SASL_AUTHID_REQUIRED |
| | | .get(mech); |
| | | throw new ArgumentException(message); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | private String getAuthzID() throws ArgumentException |
| | | { |
| | | String value = null; |
| | | for (final String s : saslOptionArg.getValues()) |
| | | { |
| | | if (s.startsWith(SASL_PROPERTY_AUTHZID)) |
| | | { |
| | | value = parseSASLOptionValue(s); |
| | | break; |
| | | } |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | private String getBindName() throws ArgumentException |
| | | { |
| | | String value = ""; |
| | | if (bindNameArg.isPresent()) |
| | | { |
| | | value = bindNameArg.getValue(); |
| | | } |
| | | else if (app.isInteractive()) |
| | | { |
| | | try { |
| | | value = app.readInput(LocalizableMessage.raw("Bind name:"), bindNameArg |
| | | .getDefaultValue() == null ? value : bindNameArg.getDefaultValue()); |
| | | } catch (CLIException e) { |
| | | throw new ArgumentException( |
| | | LocalizableMessage.raw("Unable to read bind name"), e); |
| | | } |
| | | } |
| | | |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | public BindRequest getBindRequest() throws ArgumentException |
| | | { |
| | | if(bindRequest == null) |
| | | { |
| | | String mech = null; |
| | | for (final String s : saslOptionArg.getValues()) |
| | | { |
| | | if (s.startsWith(SASL_PROPERTY_MECH)) |
| | | { |
| | | mech = parseSASLOptionValue(s); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (mech == null) |
| | | { |
| | | if (bindNameArg.isPresent() || bindPasswordFileArg.isPresent() |
| | | || bindPasswordArg.isPresent()) |
| | | { |
| | | bindRequest = Requests.newSimpleBindRequest(getBindName(), |
| | | getPassword().toCharArray()); |
| | | } |
| | | } |
| | | else if (mech.equals(DigestMD5SASLBindRequest.SASL_MECHANISM_NAME)) |
| | | { |
| | | bindRequest = Requests.newDigestMD5SASLBindRequest( |
| | | getAuthID(DigestMD5SASLBindRequest.SASL_MECHANISM_NAME), |
| | | ByteString.valueOf(getPassword())).setAuthorizationID(getAuthzID()) |
| | | .setRealm(getRealm()); |
| | | } |
| | | else if (mech.equals(CRAMMD5SASLBindRequest.SASL_MECHANISM_NAME)) |
| | | { |
| | | bindRequest = Requests.newCRAMMD5SASLBindRequest( |
| | | getAuthID(CRAMMD5SASLBindRequest.SASL_MECHANISM_NAME), ByteString |
| | | .valueOf(getPassword())); |
| | | } |
| | | else if (mech.equals(GSSAPISASLBindRequest.SASL_MECHANISM_NAME)) |
| | | { |
| | | bindRequest = Requests.newGSSAPISASLBindRequest( |
| | | getAuthID(GSSAPISASLBindRequest.SASL_MECHANISM_NAME), |
| | | ByteString.valueOf(getPassword())).setKDCAddress(getKDC()).setRealm( |
| | | getRealm()).setAuthorizationID(getAuthzID()); |
| | | } |
| | | else if (mech.equals(ExternalSASLBindRequest.SASL_MECHANISM_NAME)) |
| | | { |
| | | if (sslContext == null) |
| | | { |
| | | final LocalizableMessage message = |
| | | ERR_TOOL_SASLEXTERNAL_NEEDS_SSL_OR_TLS.get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | if (!keyStorePathArg.isPresent() && getKeyStore() == null) |
| | | { |
| | | final LocalizableMessage message = |
| | | ERR_TOOL_SASLEXTERNAL_NEEDS_KEYSTORE.get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | bindRequest = Requests.newExternalSASLBindRequest().setAuthorizationID( |
| | | getAuthzID()); |
| | | } |
| | | else if (mech.equals(PlainSASLBindRequest.SASL_MECHANISM_NAME)) |
| | | { |
| | | bindRequest = Requests.newPlainSASLBindRequest( |
| | | getAuthID(PlainSASLBindRequest.SASL_MECHANISM_NAME), |
| | | ByteString.valueOf(getPassword())).setAuthorizationID(getAuthzID()); |
| | | } |
| | | else |
| | | { |
| | | throw new ArgumentException(ERR_LDAPAUTH_UNSUPPORTED_SASL_MECHANISM |
| | | .get(mech)); |
| | | } |
| | | } |
| | | return bindRequest; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String toString() |
| | | { |
| | | return connFactory.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | private String getKDC() throws ArgumentException |
| | | { |
| | | String value = null; |
| | | for (final String s : saslOptionArg.getValues()) |
| | | { |
| | | if (s.startsWith(SASL_PROPERTY_KDC)) |
| | | { |
| | | value = parseSASLOptionValue(s); |
| | | break; |
| | | } |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a <CODE>KeyManager</CODE> object that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * |
| | | * @param keyStoreFile |
| | | * The path to the file containing the key store data. |
| | | * @return A set of <CODE>KeyManager</CODE> objects that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * @throws java.security.KeyStoreException |
| | | * If a problem occurs while interacting with the key store. |
| | | */ |
| | | |
| | | private X509KeyManager getKeyManager(String keyStoreFile) |
| | | throws KeyStoreException, IOException, NoSuchAlgorithmException, |
| | | CertificateException |
| | | { |
| | | if (keyStoreFile == null) |
| | | { |
| | | // Lookup the file name through the JDK property. |
| | | keyStoreFile = getKeyStore(); |
| | | } |
| | | |
| | | if (keyStoreFile == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | final String keyStorePass = getKeyStorePIN(); |
| | | char[] keyStorePIN = null; |
| | | if (keyStorePass != null) |
| | | { |
| | | keyStorePIN = keyStorePass.toCharArray(); |
| | | } |
| | | |
| | | final FileInputStream fos = new FileInputStream(keyStoreFile); |
| | | final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| | | keystore.load(fos, keyStorePIN); |
| | | fos.close(); |
| | | |
| | | return new ApplicationKeyManager(keystore, keyStorePIN); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Read the KeyStore from the JSSE system property. |
| | | * |
| | | * @return The path to the key store file. |
| | | */ |
| | | |
| | | private String getKeyStore() |
| | | { |
| | | return System.getProperty("javax.net.ssl.keyStore"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Read the KeyStore PIN from the JSSE system property. |
| | | * |
| | | * @return The PIN that should be used to access the key store. |
| | | */ |
| | | |
| | | private String getKeyStorePIN() |
| | | { |
| | | String pwd; |
| | | if (keyStorePasswordArg.isPresent()) |
| | | { |
| | | pwd = keyStorePasswordArg.getValue(); |
| | | } |
| | | else if (keyStorePasswordFileArg.isPresent()) |
| | | { |
| | | pwd = keyStorePasswordFileArg.getValue(); |
| | | } |
| | | else |
| | | { |
| | | pwd = System.getProperty("javax.net.ssl.keyStorePassword"); |
| | | } |
| | | return pwd; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the password which has to be used for the command. If no password was |
| | | * specified, return null. |
| | | * |
| | | * @return The password stored into the specified file on by the command line |
| | | * argument, or null it if not specified. |
| | | */ |
| | | private String getPassword() throws ArgumentException |
| | | { |
| | | String value = ""; |
| | | if (bindPasswordArg.isPresent()) |
| | | { |
| | | value = bindPasswordArg.getValue(); |
| | | } |
| | | else if (bindPasswordFileArg.isPresent()) |
| | | { |
| | | value = bindPasswordFileArg.getValue(); |
| | | } |
| | | if (value.length() == 0 && app.isInteractive()) |
| | | { |
| | | try |
| | | { |
| | | value = app.readLineOfInput(LocalizableMessage.raw("Bind Password:")); |
| | | } |
| | | catch(CLIException e) |
| | | { |
| | | throw new ArgumentException( |
| | | LocalizableMessage.raw("Unable to read password"), e); |
| | | } |
| | | } |
| | | |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | private String getRealm() throws ArgumentException |
| | | { |
| | | String value = null; |
| | | for (final String s : saslOptionArg.getValues()) |
| | | { |
| | | if (s.startsWith(SASL_PROPERTY_REALM)) |
| | | { |
| | | value = parseSASLOptionValue(s); |
| | | break; |
| | | } |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a <CODE>TrustManager</CODE> object that may be used for |
| | | * interactions requiring access to a trust manager. |
| | | * |
| | | * @return A set of <CODE>TrustManager</CODE> objects that may be used for |
| | | * interactions requiring access to a trust manager. |
| | | * @throws GeneralSecurityException |
| | | * If a problem occurs while interacting with the trust store. |
| | | */ |
| | | private TrustManager getTrustManager() throws IOException, |
| | | GeneralSecurityException |
| | | { |
| | | if (trustAllArg.isPresent()) |
| | | { |
| | | return TrustManagers.trustAll(); |
| | | } |
| | | |
| | | X509TrustManager tm = null; |
| | | if (trustStorePathArg.isPresent() |
| | | && trustStorePathArg.getValue().length() > 0) |
| | | { |
| | | tm = TrustManagers.checkValidityDates(TrustManagers.checkHostName( |
| | | hostNameArg.getValue(), TrustManagers.checkUsingTrustStore( |
| | | trustStorePathArg.getValue(), getTrustStorePIN().toCharArray(), |
| | | null))); |
| | | } |
| | | else if (getTrustStore() != null) |
| | | { |
| | | tm = TrustManagers.checkValidityDates(TrustManagers.checkHostName( |
| | | hostNameArg.getValue(), TrustManagers.checkUsingTrustStore( |
| | | getTrustStore(), getTrustStorePIN().toCharArray(), null))); |
| | | } |
| | | |
| | | if (app != null && !app.isQuiet()) |
| | | { |
| | | return new PromptingTrustManager(app, tm); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Read the TrustStore from the JSSE system property. |
| | | * |
| | | * @return The path to the trust store file. |
| | | */ |
| | | |
| | | private String getTrustStore() |
| | | { |
| | | return System.getProperty("javax.net.ssl.trustStore"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Read the TrustStore PIN from the JSSE system property. |
| | | * |
| | | * @return The PIN that should be used to access the trust store. |
| | | */ |
| | | |
| | | private String getTrustStorePIN() |
| | | { |
| | | String pwd; |
| | | if (trustStorePasswordArg.isPresent()) |
| | | { |
| | | pwd = trustStorePasswordArg.getValue(); |
| | | } |
| | | else if (trustStorePasswordFileArg.isPresent()) |
| | | { |
| | | pwd = trustStorePasswordFileArg.getValue(); |
| | | } |
| | | else |
| | | { |
| | | pwd = System.getProperty("javax.net.ssl.trustStorePassword"); |
| | | } |
| | | return pwd; |
| | | } |
| | | |
| | | |
| | | |
| | | private String parseSASLOptionValue(final String option) |
| | | throws ArgumentException |
| | | { |
| | | final int equalPos = option.indexOf('='); |
| | | if (equalPos <= 0) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_CONN_CANNOT_PARSE_SASL_OPTION |
| | | .get(option); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | return option.substring(equalPos + 1, option.length()); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.INFO_ERROR_EMPTY_RESPONSE; |
| | | import static com.sun.opends.sdk.messages.Messages.INFO_MENU_PROMPT_RETURN_TO_CONTINUE; |
| | | import static com.sun.opends.sdk.messages.Messages.INFO_PROMPT_SINGLE_DEFAULT; |
| | | import static com.sun.opends.sdk.tools.Utils.MAX_LINE_WIDTH; |
| | | import static com.sun.opends.sdk.tools.Utils.wrapText; |
| | | |
| | | import java.io.*; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides an abstract base class which can be used as the basis of |
| | | * a console-based application. |
| | | */ |
| | | abstract class ConsoleApplication |
| | | { |
| | | private static final class NullOutputStream extends OutputStream |
| | | { |
| | | /** |
| | | * The singleton instance for this class. |
| | | */ |
| | | private static final NullOutputStream INSTANCE = new NullOutputStream(); |
| | | |
| | | /** |
| | | * The singleton print stream tied to the null output stream. |
| | | */ |
| | | private static final PrintStream PRINT_STREAM = new PrintStream(INSTANCE); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a print stream using this null output stream. |
| | | * |
| | | * @return A print stream using this null output stream. |
| | | */ |
| | | static PrintStream printStream() |
| | | { |
| | | return PRINT_STREAM; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this null output stream. |
| | | */ |
| | | private NullOutputStream() |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Closes the output stream. This has no effect. |
| | | */ |
| | | @Override |
| | | public void close() |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Flushes the output stream. This has no effect. |
| | | */ |
| | | @Override |
| | | public void flush() |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Writes the provided data to this output stream. This has no effect. |
| | | * |
| | | * @param b |
| | | * The byte array containing the data to be written. |
| | | */ |
| | | @Override |
| | | public void write(final byte[] b) |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Writes the provided data to this output stream. This has no effect. |
| | | * |
| | | * @param b |
| | | * The byte array containing the data to be written. |
| | | * @param off |
| | | * The offset at which the real data begins. |
| | | * @param len |
| | | * The number of bytes to be written. |
| | | */ |
| | | @Override |
| | | public void write(final byte[] b, final int off, final int len) |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Writes the provided byte to this output stream. This has no effect. |
| | | * |
| | | * @param b |
| | | * The byte to be written. |
| | | */ |
| | | @Override |
| | | public void write(final int b) |
| | | { |
| | | // No implementation is required. |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * A null reader. |
| | | */ |
| | | private static final class NullReader extends Reader |
| | | { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void close() throws IOException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int read(final char[] cbuf, final int off, final int len) |
| | | throws IOException |
| | | { |
| | | return -1; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // The error stream which this application should use. |
| | | private final PrintStream err; |
| | | |
| | | // The input stream reader which this application should use. |
| | | private final BufferedReader reader; |
| | | |
| | | private final InputStream in; |
| | | |
| | | // The output stream which this application should use. |
| | | private final PrintStream out; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new console application instance. |
| | | * |
| | | * @param in |
| | | * The application input stream. |
| | | * @param out |
| | | * The application output stream. |
| | | * @param err |
| | | * The application error stream. |
| | | */ |
| | | ConsoleApplication(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | this.in = in; |
| | | if (in != null) |
| | | { |
| | | this.reader = new BufferedReader(new InputStreamReader(in)); |
| | | } |
| | | else |
| | | { |
| | | this.reader = new BufferedReader(new NullReader()); |
| | | } |
| | | |
| | | if (out != null) |
| | | { |
| | | this.out = new PrintStream(out); |
| | | } |
| | | else |
| | | { |
| | | this.out = NullOutputStream.printStream(); |
| | | } |
| | | |
| | | if (err != null) |
| | | { |
| | | this.err = new PrintStream(err); |
| | | } |
| | | else |
| | | { |
| | | this.err = NullOutputStream.printStream(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the application error stream. |
| | | * |
| | | * @return Returns the application error stream. |
| | | */ |
| | | final PrintStream getErrorStream() |
| | | { |
| | | return err; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the application input stream reader. |
| | | * |
| | | * @return Returns the application input stream. |
| | | */ |
| | | final BufferedReader getInputReader() |
| | | { |
| | | return reader; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the application input stream. |
| | | * |
| | | * @return Returns the application input stream. |
| | | */ |
| | | final InputStream getInputStream() |
| | | { |
| | | return in; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the application output stream. |
| | | * |
| | | * @return Returns the application output stream. |
| | | */ |
| | | final PrintStream getOutputStream() |
| | | { |
| | | return out; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | abstract boolean isAdvancedMode(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | abstract boolean isInteractive(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | abstract boolean isMenuDrivenMode(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | abstract boolean isQuiet(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | abstract boolean isScriptFriendly(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | abstract boolean isVerbose(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Interactively prompts the user to press return to continue. This method |
| | | * should be called in situations where a user needs to be given a chance to |
| | | * read some documentation before continuing (continuing may cause the |
| | | * documentation to be scrolled out of view). |
| | | */ |
| | | final void pressReturnToContinue() |
| | | { |
| | | final LocalizableMessage msg = INFO_MENU_PROMPT_RETURN_TO_CONTINUE.get(); |
| | | try |
| | | { |
| | | readLineOfInput(msg); |
| | | } |
| | | catch (final CLIException e) |
| | | { |
| | | // Ignore the exception - applications don't care. |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a message to the error stream. |
| | | * |
| | | * @param msg |
| | | * The message. |
| | | */ |
| | | final void print(final LocalizableMessage msg) |
| | | { |
| | | err.print(wrapText(msg, MAX_LINE_WIDTH)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a blank line to the error stream. |
| | | */ |
| | | final void println() |
| | | { |
| | | err.println(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a message to the error stream. |
| | | * |
| | | * @param msg |
| | | * The message. |
| | | */ |
| | | final void println(final LocalizableMessage msg) |
| | | { |
| | | err.println(wrapText(msg, MAX_LINE_WIDTH)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a message to the error stream indented by the specified number of |
| | | * columns. |
| | | * |
| | | * @param msg |
| | | * The message. |
| | | * @param indent |
| | | * The number of columns to indent. |
| | | */ |
| | | final void println(final LocalizableMessage msg, final int indent) |
| | | { |
| | | err.println(wrapText(msg, MAX_LINE_WIDTH, indent)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a blank line to the output stream if we are not in quiet mode. |
| | | */ |
| | | final void printlnProgress() |
| | | { |
| | | if (!isQuiet()) |
| | | { |
| | | out.println(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a message to the output stream if we are not in quiet mode. |
| | | * |
| | | * @param msg |
| | | * The message. |
| | | */ |
| | | final void printProgress(final LocalizableMessage msg) |
| | | { |
| | | if (!isQuiet()) |
| | | { |
| | | out.print(msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Displays a message to the error stream if verbose mode is enabled. |
| | | * |
| | | * @param msg |
| | | * The verbose message. |
| | | */ |
| | | final void printVerboseMessage(final LocalizableMessage msg) |
| | | { |
| | | if (isVerbose() || isInteractive()) |
| | | { |
| | | err.println(wrapText(msg, MAX_LINE_WIDTH)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Commodity method that interactively prompts (on error output) the user to |
| | | * provide a string value. Any non-empty string will be allowed (the empty |
| | | * string will indicate that the default should be used, if there is one). |
| | | * |
| | | * @param prompt |
| | | * The prompt to present to the user. |
| | | * @param defaultValue |
| | | * The default value to assume if the user presses ENTER without |
| | | * typing anything, or <CODE>null</CODE> if there should not be a |
| | | * default and the user must explicitly provide a value. |
| | | * @throws CLIException |
| | | * If the line of input could not be retrieved for some reason. |
| | | * @return The string value read from the user. |
| | | */ |
| | | final String readInput(LocalizableMessage prompt, final String defaultValue) |
| | | throws CLIException |
| | | { |
| | | while (true) |
| | | { |
| | | if (defaultValue != null) |
| | | { |
| | | prompt = INFO_PROMPT_SINGLE_DEFAULT |
| | | .get(prompt.toString(), defaultValue); |
| | | } |
| | | final String response = readLineOfInput(prompt); |
| | | |
| | | if ("".equals(response)) |
| | | { |
| | | if (defaultValue == null) |
| | | { |
| | | print(INFO_ERROR_EMPTY_RESPONSE.get()); |
| | | } |
| | | else |
| | | { |
| | | return defaultValue; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | return response; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Commodity method that interactively prompts (on error output) the user to |
| | | * provide a string value. Any non-empty string will be allowed (the empty |
| | | * string will indicate that the default should be used, if there is one). If |
| | | * an error occurs a message will be logged to the provided logger. |
| | | * |
| | | * @param prompt |
| | | * The prompt to present to the user. |
| | | * @param defaultValue |
| | | * The default value to assume if the user presses ENTER without |
| | | * typing anything, or <CODE>null</CODE> if there should not be a |
| | | * default and the user must explicitly provide a value. |
| | | * @param logger |
| | | * the Logger to be used to log the error message. |
| | | * @return The string value read from the user. |
| | | */ |
| | | final String readInput(final LocalizableMessage prompt, |
| | | final String defaultValue, final Logger logger) |
| | | { |
| | | String s = defaultValue; |
| | | try |
| | | { |
| | | s = readInput(prompt, defaultValue); |
| | | } |
| | | catch (final CLIException ce) |
| | | { |
| | | logger.log(Level.WARNING, "Error reading input: " + ce, ce); |
| | | } |
| | | return s; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Interactively retrieves a line of input from the console. |
| | | * |
| | | * @param prompt |
| | | * The prompt. |
| | | * @return Returns the line of input, or <code>null</code> if the end of input |
| | | * has been reached. |
| | | * @throws CLIException |
| | | * If the line of input could not be retrieved for some reason. |
| | | */ |
| | | final String readLineOfInput(final LocalizableMessage prompt) |
| | | throws CLIException |
| | | { |
| | | if (prompt != null) |
| | | { |
| | | err.print(wrapText(prompt, MAX_LINE_WIDTH)); |
| | | err.print(" "); |
| | | } |
| | | try |
| | | { |
| | | final String s = reader.readLine(); |
| | | if (s == null) |
| | | { |
| | | throw CLIException |
| | | .adaptInputException(new EOFException("End of input")); |
| | | } |
| | | else |
| | | { |
| | | return s; |
| | | } |
| | | } |
| | | catch (final IOException e) |
| | | { |
| | | throw CLIException.adaptInputException(e); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.FileReader; |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | import com.sun.opends.sdk.util.Validator; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | |
| | | |
| | | /** |
| | | * A source of data for performance tools. |
| | | */ |
| | | final class DataSource |
| | | { |
| | | private static interface IDataSource |
| | | { |
| | | public IDataSource duplicate(); |
| | | |
| | | |
| | | |
| | | public Object getData(); |
| | | } |
| | | |
| | | |
| | | |
| | | private static class IncrementLineFileDataSource implements IDataSource |
| | | { |
| | | private final List<String> lines; |
| | | private int next; |
| | | |
| | | |
| | | |
| | | public IncrementLineFileDataSource(final String file) throws IOException |
| | | { |
| | | lines = new ArrayList<String>(); |
| | | final BufferedReader in = new BufferedReader(new FileReader(file)); |
| | | try |
| | | { |
| | | String line; |
| | | while ((line = in.readLine()) != null) |
| | | { |
| | | lines.add(line); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | in.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private IncrementLineFileDataSource(final List<String> lines) |
| | | { |
| | | this.lines = lines; |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | return new IncrementLineFileDataSource(lines); |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | if (next == lines.size()) |
| | | { |
| | | next = 0; |
| | | } |
| | | |
| | | return lines.get(next++); |
| | | } |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | return LocalizableMessage.raw( |
| | | "\"inc({filename})\" Consecutive, incremental line from file"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static class IncrementNumberDataSource implements IDataSource |
| | | { |
| | | private final int low; |
| | | private int next; |
| | | private final int high; |
| | | |
| | | |
| | | |
| | | public IncrementNumberDataSource(final int low, final int high) |
| | | { |
| | | this.low = this.next = low; |
| | | this.high = high; |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | return new IncrementNumberDataSource(low, high); |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | if (next == high) |
| | | { |
| | | next = low; |
| | | return high; |
| | | } |
| | | |
| | | return next++; |
| | | } |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | return LocalizableMessage.raw( |
| | | "\"inc({min},{max})\" Consecutive, incremental number"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static class RandomLineFileDataSource implements IDataSource |
| | | { |
| | | private final List<String> lines; |
| | | private final Random random; |
| | | |
| | | |
| | | |
| | | public RandomLineFileDataSource(final long seed, final String file) |
| | | throws IOException |
| | | { |
| | | lines = new ArrayList<String>(); |
| | | random = new Random(seed); |
| | | final BufferedReader in = new BufferedReader(new FileReader(file)); |
| | | try |
| | | { |
| | | String line; |
| | | while ((line = in.readLine()) != null) |
| | | { |
| | | lines.add(line); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | in.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | return lines.get(random.nextInt(lines.size())); |
| | | } |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | return LocalizableMessage.raw( |
| | | "\"rand({filename})\" Random line from file"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static class RandomNumberDataSource implements IDataSource |
| | | { |
| | | private final Random random; |
| | | private final int offset; |
| | | private final int range; |
| | | |
| | | |
| | | |
| | | public RandomNumberDataSource(final long seed, final int low, final int high) |
| | | { |
| | | random = new Random(seed); |
| | | offset = low; |
| | | range = high - low; |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | // There is no state info so threads can just share one instance. |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | return random.nextInt(range) + offset; |
| | | } |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | return LocalizableMessage.raw( |
| | | "\"rand({min},{max})\" Random number"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class RandomStringDataSource implements IDataSource |
| | | { |
| | | private final Random random; |
| | | private final int length; |
| | | private final Character[] charSet; |
| | | |
| | | |
| | | |
| | | private RandomStringDataSource(final int seed, final int length, |
| | | final String charSet) |
| | | { |
| | | this.length = length; |
| | | final Set<Character> chars = new HashSet<Character>(); |
| | | for (int i = 0; i < charSet.length(); i++) |
| | | { |
| | | final char c = charSet.charAt(i); |
| | | if (c == '[') |
| | | { |
| | | i += 1; |
| | | final char start = charSet.charAt(i); |
| | | i += 2; |
| | | final char end = charSet.charAt(i); |
| | | i += 1; |
| | | for (int j = start; j <= end; j++) |
| | | { |
| | | chars.add((char) j); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | chars.add(c); |
| | | } |
| | | } |
| | | this.charSet = chars.toArray(new Character[chars.size()]); |
| | | this.random = new Random(seed); |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | final char[] str = new char[length]; |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | str[i] = charSet[random.nextInt(charSet.length)]; |
| | | } |
| | | return new String(str); |
| | | } |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | return LocalizableMessage.raw( |
| | | "\"randStr({length},<charSet>)\" Random string of specified " + |
| | | "length and optionally from characters in " + |
| | | "the charSet string. A range of character " + |
| | | "can be specified with [start-end] charSet notation. " + |
| | | "If no charSet is specified, the default charSet of " + |
| | | "[A-Z][a-z][0-9] will be used"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class StaticDataSource implements IDataSource |
| | | { |
| | | private final Object data; |
| | | |
| | | |
| | | |
| | | private StaticDataSource(final Object data) |
| | | { |
| | | this.data = data; |
| | | } |
| | | |
| | | |
| | | |
| | | public IDataSource duplicate() |
| | | { |
| | | // There is no state info so threads can just share one instance. |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | return data; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns Generated data from the specified data sources. Generated data will |
| | | * be placed in the specified data array. If the data array is null or smaller |
| | | * than the number of data sources, one will be allocated. |
| | | * |
| | | * @param dataSources |
| | | * Data sources that will generate arguments referenced by the format |
| | | * specifiers in the format string. |
| | | * @param data |
| | | * The array where genereated data will be placed to format the |
| | | * string. |
| | | * @return A formatted string |
| | | */ |
| | | public static Object[] generateData(final DataSource[] dataSources, |
| | | Object[] data) |
| | | { |
| | | if (data == null || data.length < dataSources.length) |
| | | { |
| | | data = new Object[dataSources.length]; |
| | | } |
| | | for (int i = 0; i < dataSources.length; i++) |
| | | { |
| | | data[i] = dataSources[i].getData(); |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses a list of source definitions into an array of data source objects. A |
| | | * data source is defined as follows: - rand({min},{max}) generates a random |
| | | * integer between the min and max. - rand({filename}) retrieves a random line |
| | | * from a file. - inc({min},{max}) returns incremental integer between the min |
| | | * and max. - inc({filename}) retrieves lines in order from a file. - {number} |
| | | * always return the integer as given. - {string} always return the string as |
| | | * given. |
| | | * |
| | | * @param sources |
| | | * The list of source definitions to parse. |
| | | * @return The array of parsed data sources. |
| | | * @throws ArgumentException |
| | | * If an exception occurs while parsing. |
| | | */ |
| | | public static DataSource[] parse(final List<String> sources) |
| | | throws ArgumentException |
| | | { |
| | | Validator.ensureNotNull(sources); |
| | | final DataSource[] dataSources = new DataSource[sources.size()]; |
| | | for (int i = 0; i < sources.size(); i++) |
| | | { |
| | | final String dataSourceDef = sources.get(i); |
| | | if (dataSourceDef.startsWith("rand(") && dataSourceDef.endsWith(")")) |
| | | { |
| | | final int lparenPos = dataSourceDef.indexOf("("); |
| | | final int commaPos = dataSourceDef.indexOf(","); |
| | | final int rparenPos = dataSourceDef.indexOf(")"); |
| | | |
| | | if (commaPos < 0) |
| | | { |
| | | try |
| | | { |
| | | // This is a file name |
| | | dataSources[i] = new DataSource(new RandomLineFileDataSource(0, |
| | | dataSourceDef.substring(lparenPos + 1, rparenPos))); |
| | | } |
| | | catch(IOException ioe) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error opening file %s: %s", |
| | | dataSourceDef.substring(lparenPos + 1, rparenPos), |
| | | ioe.getMessage()), ioe); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error parsing value generator: %s", e.getMessage()), e); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | // This range of integers |
| | | final int low = Integer.parseInt(dataSourceDef.substring( |
| | | lparenPos + 1, commaPos)); |
| | | final int high = Integer.parseInt(dataSourceDef.substring( |
| | | commaPos + 1, rparenPos)); |
| | | dataSources[i] = new DataSource(new RandomNumberDataSource(Thread |
| | | .currentThread().getId(), low, high)); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error parsing value generator: %s", e.getMessage()), e); |
| | | } |
| | | } |
| | | |
| | | } |
| | | else if (dataSourceDef.startsWith("randstr(") |
| | | && dataSourceDef.endsWith(")")) |
| | | { |
| | | final int lparenPos = dataSourceDef.indexOf("("); |
| | | final int commaPos = dataSourceDef.indexOf(","); |
| | | final int rparenPos = dataSourceDef.indexOf(")"); |
| | | int length; |
| | | String charSet; |
| | | try |
| | | { |
| | | if (commaPos < 0) |
| | | { |
| | | length = Integer.parseInt(dataSourceDef.substring(lparenPos + 1, |
| | | rparenPos)); |
| | | charSet = "[A-Z][a-z][0-9]"; |
| | | } |
| | | else |
| | | { |
| | | // length and charSet |
| | | length = Integer.parseInt(dataSourceDef.substring(lparenPos + 1, |
| | | commaPos)); |
| | | charSet = dataSourceDef.substring(commaPos + 1, rparenPos); |
| | | } |
| | | dataSources[i] = new DataSource(new RandomStringDataSource(0, length, |
| | | charSet)); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error parsing value generator: %s", e.getMessage()), e); |
| | | } |
| | | } |
| | | else if (dataSourceDef.startsWith("inc(") && dataSourceDef.endsWith(")")) |
| | | { |
| | | final int lparenPos = dataSourceDef.indexOf("("); |
| | | final int commaPos = dataSourceDef.indexOf(","); |
| | | final int rparenPos = dataSourceDef.indexOf(")"); |
| | | if (commaPos < 0) |
| | | { |
| | | try |
| | | { |
| | | // This is a file name |
| | | dataSources[i] = new DataSource(new IncrementLineFileDataSource( |
| | | dataSourceDef.substring(lparenPos + 1, rparenPos))); |
| | | } |
| | | catch(IOException ioe) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error opening file %s: %s", |
| | | dataSourceDef.substring(lparenPos + 1, rparenPos), |
| | | ioe.getMessage()), ioe); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error parsing value generator: %s", e.getMessage()), e); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | final int low = Integer.parseInt(dataSourceDef.substring( |
| | | lparenPos + 1, commaPos)); |
| | | final int high = Integer.parseInt(dataSourceDef.substring( |
| | | commaPos + 1, rparenPos)); |
| | | dataSources[i] = new DataSource(new IncrementNumberDataSource(low, |
| | | high)); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw( |
| | | "Error parsing value generator: %s", e.getMessage()), e); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | dataSources[i] = new DataSource(new StaticDataSource(Integer |
| | | .parseInt(dataSourceDef))); |
| | | } |
| | | catch (final NumberFormatException nfe) |
| | | { |
| | | dataSources[i] = new DataSource(new StaticDataSource(dataSourceDef)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return dataSources; |
| | | } |
| | | |
| | | |
| | | public static LocalizableMessage getUsage() |
| | | { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append(IncrementLineFileDataSource.getUsage()); |
| | | builder.append(StaticUtils.EOL); |
| | | builder.append(IncrementNumberDataSource.getUsage()); |
| | | builder.append(StaticUtils.EOL); |
| | | builder.append(RandomLineFileDataSource.getUsage()); |
| | | builder.append(StaticUtils.EOL); |
| | | builder.append(RandomNumberDataSource.getUsage()); |
| | | builder.append(StaticUtils.EOL); |
| | | builder.append(RandomStringDataSource.getUsage()); |
| | | return LocalizableMessage.raw(builder.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | private final IDataSource impl; |
| | | |
| | | |
| | | |
| | | private DataSource(final IDataSource impl) |
| | | { |
| | | this.impl = impl; |
| | | } |
| | | |
| | | |
| | | |
| | | public DataSource duplicate() |
| | | { |
| | | final IDataSource dup = impl.duplicate(); |
| | | if (dup == impl) |
| | | { |
| | | return this; |
| | | } |
| | | else |
| | | { |
| | | return new DataSource(dup); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public Object getData() |
| | | { |
| | | return impl.getData(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.File; |
| | | import java.io.FileReader; |
| | | import java.util.LinkedHashMap; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an argument whose value will be read from a file rather |
| | | * than actually specified on the command-line. When a value is specified on the |
| | | * command line, it will be treated as the path to the file containing the |
| | | * actual value rather than the value itself. <BR> |
| | | * <BR> |
| | | * Note that if if no filename is provided on the command line but a default |
| | | * value is specified programatically or if the default value is read from a |
| | | * specified property, then that default value will be taken as the actual value |
| | | * rather than a filename. <BR> |
| | | * <BR> |
| | | * Also note that this argument type assumes that the entire value for the |
| | | * argument is on a single line in the specified file. If the file contains |
| | | * multiple lines, then only the first line will be read. |
| | | */ |
| | | final class FileBasedArgument extends Argument |
| | | { |
| | | // The mapping between filenames specified and the first lines read |
| | | // from those |
| | | // files. |
| | | private final LinkedHashMap<String, String> namesToValues; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new file-based argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public FileBasedArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final LocalizableMessage valuePlaceholder, |
| | | final String defaultValue, final String propertyName, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | true, valuePlaceholder, defaultValue, propertyName, description); |
| | | |
| | | namesToValues = new LinkedHashMap<String, String>(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new file-based argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public FileBasedArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final LocalizableMessage valuePlaceholder, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, false, true, |
| | | valuePlaceholder, null, null, description); |
| | | |
| | | namesToValues = new LinkedHashMap<String, String>(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a value to the set of values for this argument. This should only be |
| | | * called if the value is allowed by the <CODE>valueIsAcceptable</CODE> |
| | | * method. Note that in this case, correct behavior depends on a previous |
| | | * successful call to <CODE>valueIsAcceptable</CODE> so that the value read |
| | | * from the file may be stored in the name-to-value hash and used in place of |
| | | * the filename here. |
| | | * |
| | | * @param valueString |
| | | * The string representation of the value to add to this argument. |
| | | */ |
| | | @Override |
| | | public void addValue(final String valueString) |
| | | { |
| | | final String actualValue = namesToValues.get(valueString); |
| | | if (actualValue != null) |
| | | { |
| | | super.addValue(actualValue); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a map between the filenames specified on the command line and the |
| | | * first lines read from those files. |
| | | * |
| | | * @return A map between the filenames specified on the command line and the |
| | | * first lines read from those files. |
| | | */ |
| | | public LinkedHashMap<String, String> getNameToValueMap() |
| | | { |
| | | return namesToValues; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | @Override |
| | | public boolean valueIsAcceptable(final String valueString, |
| | | final LocalizableMessageBuilder invalidReason) |
| | | { |
| | | // First, make sure that the specified file exists. |
| | | File valueFile; |
| | | try |
| | | { |
| | | valueFile = new File(valueString); |
| | | if (!valueFile.exists()) |
| | | { |
| | | invalidReason.append(ERR_FILEARG_NO_SUCH_FILE.get(valueString, |
| | | getName())); |
| | | return false; |
| | | } |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | invalidReason.append(ERR_FILEARG_CANNOT_VERIFY_FILE_EXISTENCE.get( |
| | | valueString, getName(), getExceptionMessage(e))); |
| | | return false; |
| | | } |
| | | |
| | | // Open the file for reading. |
| | | BufferedReader reader; |
| | | try |
| | | { |
| | | reader = new BufferedReader(new FileReader(valueFile)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | invalidReason.append(ERR_FILEARG_CANNOT_OPEN_FILE.get(valueString, |
| | | getName(), getExceptionMessage(e))); |
| | | return false; |
| | | } |
| | | |
| | | // Read the first line and close the file. |
| | | String line; |
| | | try |
| | | { |
| | | line = reader.readLine(); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | invalidReason.append(ERR_FILEARG_CANNOT_READ_FILE.get(valueString, |
| | | getName(), getExceptionMessage(e))); |
| | | return false; |
| | | } |
| | | finally |
| | | { |
| | | try |
| | | { |
| | | reader.close(); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | } |
| | | } |
| | | |
| | | // If the line read is null, then that means the file was empty. |
| | | if (line == null) |
| | | { |
| | | |
| | | invalidReason.append(ERR_FILEARG_EMPTY_FILE.get(valueString, getName())); |
| | | return false; |
| | | } |
| | | |
| | | // Store the value in the hash so it will be available for addValue. |
| | | // We |
| | | // won't do any validation on the value itself, so anything that we |
| | | // read |
| | | // will be considered acceptable. |
| | | namesToValues.put(valueString, line); |
| | | return true; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ARG_CANNOT_DECODE_AS_INT; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_INTARG_VALUE_BELOW_LOWER_BOUND; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an argument type that will only accept integer values, and |
| | | * potentially only those in a given range. |
| | | */ |
| | | final class IntegerArgument extends Argument |
| | | { |
| | | // Indicates whether a lower bound will be enforced for this argument. |
| | | private final boolean hasLowerBound; |
| | | |
| | | // Indicates whether an upper bound will be enforced for this |
| | | // argument. |
| | | private final boolean hasUpperBound; |
| | | |
| | | // The lower bound that will be enforced for this argument. |
| | | private final double lowerBound; |
| | | |
| | | // The upper bound that will be enforced for this argument. |
| | | private final double upperBound; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param hasLowerBound |
| | | * Indicates whether a lower bound should be enforced for values of |
| | | * this argument. |
| | | * @param lowerBound |
| | | * The lower bound that should be enforced for values of this |
| | | * argument. |
| | | * @param hasUpperBound |
| | | * Indicates whether an upperbound should be enforced for values of |
| | | * this argument. |
| | | * @param upperBound |
| | | * The upper bound that should be enforced for values of this |
| | | * argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final double defaultValue, |
| | | final String propertyName, final boolean hasLowerBound, |
| | | final double lowerBound, final boolean hasUpperBound, |
| | | final double upperBound, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, String.valueOf(defaultValue), |
| | | propertyName, description); |
| | | |
| | | this.hasLowerBound = hasLowerBound; |
| | | this.hasUpperBound = hasUpperBound; |
| | | this.lowerBound = lowerBound; |
| | | this.upperBound = upperBound; |
| | | |
| | | if (hasLowerBound && hasUpperBound && (lowerBound > upperBound)) |
| | | { |
| | | final LocalizableMessage message = ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND |
| | | .get(name, lowerBound, upperBound); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final double defaultValue, |
| | | final String propertyName, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, String.format("%f", defaultValue), |
| | | propertyName, description); |
| | | |
| | | hasLowerBound = false; |
| | | hasUpperBound = false; |
| | | lowerBound = Integer.MIN_VALUE; |
| | | upperBound = Integer.MAX_VALUE; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param hasLowerBound |
| | | * Indicates whether a lower bound should be enforced for values of |
| | | * this argument. |
| | | * @param lowerBound |
| | | * The lower bound that should be enforced for values of this |
| | | * argument. |
| | | * @param hasUpperBound |
| | | * Indicates whether an upperbound should be enforced for values of |
| | | * this argument. |
| | | * @param upperBound |
| | | * The upper bound that should be enforced for values of this |
| | | * argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final int defaultValue, |
| | | final String propertyName, final boolean hasLowerBound, |
| | | final double lowerBound, final boolean hasUpperBound, |
| | | final double upperBound, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, String.valueOf(defaultValue), |
| | | propertyName, description); |
| | | |
| | | this.hasLowerBound = hasLowerBound; |
| | | this.hasUpperBound = hasUpperBound; |
| | | this.lowerBound = lowerBound; |
| | | this.upperBound = upperBound; |
| | | |
| | | if (hasLowerBound && hasUpperBound && (lowerBound > upperBound)) |
| | | { |
| | | final LocalizableMessage message = ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND |
| | | .get(name, lowerBound, upperBound); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final int defaultValue, |
| | | final String propertyName, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, String.valueOf(defaultValue), |
| | | propertyName, description); |
| | | |
| | | hasLowerBound = false; |
| | | hasUpperBound = false; |
| | | lowerBound = Integer.MIN_VALUE; |
| | | upperBound = Integer.MAX_VALUE; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param hasLowerBound |
| | | * Indicates whether a lower bound should be enforced for values of |
| | | * this argument. |
| | | * @param lowerBound |
| | | * The lower bound that should be enforced for values of this |
| | | * argument. |
| | | * @param hasUpperBound |
| | | * Indicates whether an upperbound should be enforced for values of |
| | | * this argument. |
| | | * @param upperBound |
| | | * The upper bound that should be enforced for values of this |
| | | * argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean needsValue, final LocalizableMessage valuePlaceholder, |
| | | final boolean hasLowerBound, final double lowerBound, |
| | | final boolean hasUpperBound, final double upperBound, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, |
| | | valuePlaceholder, null, null, description); |
| | | |
| | | this.hasLowerBound = hasLowerBound; |
| | | this.hasUpperBound = hasUpperBound; |
| | | this.lowerBound = lowerBound; |
| | | this.upperBound = upperBound; |
| | | |
| | | if (hasLowerBound && hasUpperBound && (lowerBound > upperBound)) |
| | | { |
| | | final LocalizableMessage message = ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND |
| | | .get(name, lowerBound, upperBound); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new integer argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public IntegerArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean needsValue, final LocalizableMessage valuePlaceholder, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, |
| | | valuePlaceholder, null, null, description); |
| | | |
| | | hasLowerBound = false; |
| | | hasUpperBound = false; |
| | | lowerBound = Double.MIN_VALUE; |
| | | upperBound = Double.MAX_VALUE; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the lower bound that may be enforced for values of this argument. |
| | | * |
| | | * @return The lower bound that may be enforced for values of this argument. |
| | | */ |
| | | public double getLowerBound() |
| | | { |
| | | return lowerBound; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the upper bound that may be enforced for values of this argument. |
| | | * |
| | | * @return The upper bound that may be enforced for values of this argument. |
| | | */ |
| | | public double getUpperBound() |
| | | { |
| | | return upperBound; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether a lower bound should be enforced for values of this |
| | | * argument. |
| | | * |
| | | * @return <CODE>true</CODE> if a lower bound should be enforced for values of |
| | | * this argument, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean hasLowerBound() |
| | | { |
| | | return hasLowerBound; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether a upper bound should be enforced for values of this |
| | | * argument. |
| | | * |
| | | * @return <CODE>true</CODE> if a upper bound should be enforced for values of |
| | | * this argument, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean hasUpperBound() |
| | | { |
| | | return hasUpperBound; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | @Override |
| | | public boolean valueIsAcceptable(final String valueString, |
| | | final LocalizableMessageBuilder invalidReason) |
| | | { |
| | | // First, the value must be decodable as an integer. |
| | | double intValue; |
| | | try |
| | | { |
| | | intValue = Double.parseDouble(valueString); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | invalidReason.append(ERR_ARG_CANNOT_DECODE_AS_INT.get(valueString, |
| | | getName())); |
| | | return false; |
| | | } |
| | | |
| | | // If there is a lower bound, then the value must be greater than or |
| | | // equal to it. |
| | | if (hasLowerBound && (intValue < lowerBound)) |
| | | { |
| | | invalidReason.append(ERR_INTARG_VALUE_BELOW_LOWER_BOUND.get(getName(), |
| | | intValue, lowerBound)); |
| | | return false; |
| | | } |
| | | |
| | | // If there is an upper bound, then the value must be less than or |
| | | // equal to it. |
| | | if (hasUpperBound && (intValue > upperBound)) |
| | | { |
| | | |
| | | invalidReason.append(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get(getName(), |
| | | intValue, upperBound)); |
| | | return false; |
| | | } |
| | | |
| | | // At this point, the value should be acceptable. |
| | | return true; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.*; |
| | | import java.util.ArrayList; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.controls.AssertionRequestControl; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.controls.ProxiedAuthV2RequestControl; |
| | | import org.opends.sdk.requests.CompareRequest; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.responses.Responses; |
| | | import org.opends.sdk.responses.Result; |
| | | |
| | | import com.sun.opends.sdk.util.Base64; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A tool that can be used to issue Compare requests to the Directory Server. |
| | | */ |
| | | public final class LDAPCompare extends ConsoleApplication |
| | | { |
| | | /** |
| | | * The main method for LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainCompare(args, System.in, System.out, System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainCompare(final String[] args) |
| | | { |
| | | return mainCompare(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. specified, |
| | | * the number of matching entries should be returned or not. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | static int mainCompare(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | { |
| | | return new LDAPCompare(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | |
| | | |
| | | private LDAPCompare(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int executeCompare(final CompareRequest request, |
| | | final Connection connection) |
| | | { |
| | | println(INFO_PROCESSING_COMPARE_OPERATION.get(request |
| | | .getAttributeDescription().toString(), request |
| | | .getAssertionValueAsString(), request.getName().toString())); |
| | | if (connection != null) |
| | | { |
| | | try |
| | | { |
| | | Result result; |
| | | try |
| | | { |
| | | result = connection.compare(request); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | result = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(result); |
| | | } |
| | | |
| | | if (result.getResultCode() == ResultCode.COMPARE_FALSE) |
| | | { |
| | | println(INFO_COMPARE_OPERATION_RESULT_FALSE.get(request.getName() |
| | | .toString())); |
| | | } |
| | | else |
| | | { |
| | | |
| | | println(INFO_COMPARE_OPERATION_RESULT_TRUE.get(request.getName() |
| | | .toString())); |
| | | } |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | final LocalizableMessage msg = INFO_OPERATION_FAILED.get("COMPARE"); |
| | | println(msg); |
| | | final Result r = ere.getResult(); |
| | | println(ERR_TOOL_RESULT_CODE.get(r.getResultCode().intValue(), r |
| | | .getResultCode().toString())); |
| | | if ((r.getDiagnosticMessage() != null) |
| | | && (r.getDiagnosticMessage().length() > 0)) |
| | | { |
| | | println(LocalizableMessage.raw(r.getDiagnosticMessage())); |
| | | } |
| | | if (r.getMatchedDN() != null && r.getMatchedDN().length() > 0) |
| | | { |
| | | println(ERR_TOOL_MATCHED_DN.get(r.getMatchedDN())); |
| | | } |
| | | return r.getResultCode().intValue(); |
| | | } |
| | | } |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_LDAPCOMPARE_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser(LDAPCompare.class |
| | | .getName(), toolDescription, false, true, 1, 0, |
| | | "attribute:value [DN ...]"); |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | |
| | | BooleanArgument continueOnError; |
| | | BooleanArgument noop; |
| | | BooleanArgument showUsage; |
| | | IntegerArgument version; |
| | | StringArgument assertionFilter; |
| | | StringArgument controlStr; |
| | | StringArgument encodingStr; |
| | | StringArgument filename; |
| | | StringArgument proxyAuthzID; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | |
| | | try |
| | | { |
| | | connectionFactoryProvider = |
| | | new ConnectionFactoryProvider(argParser, this); |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | filename = new StringArgument("filename", OPTION_SHORT_FILENAME, |
| | | OPTION_LONG_FILENAME, false, false, true, |
| | | INFO_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_LDAPMODIFY_DESCRIPTION_FILENAME.get()); |
| | | filename.setPropertyName(OPTION_LONG_FILENAME); |
| | | argParser.addArgument(filename); |
| | | |
| | | proxyAuthzID = new StringArgument("proxy_authzid", |
| | | OPTION_SHORT_PROXYAUTHID, OPTION_LONG_PROXYAUTHID, false, false, |
| | | true, INFO_PROXYAUTHID_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROXY_AUTHZID.get()); |
| | | proxyAuthzID.setPropertyName(OPTION_LONG_PROXYAUTHID); |
| | | argParser.addArgument(proxyAuthzID); |
| | | |
| | | assertionFilter = new StringArgument("assertionfilter", null, |
| | | OPTION_LONG_ASSERTION_FILE, false, false, true, |
| | | INFO_ASSERTION_FILTER_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ASSERTION_FILTER.get()); |
| | | assertionFilter.setPropertyName(OPTION_LONG_ASSERTION_FILE); |
| | | argParser.addArgument(assertionFilter); |
| | | |
| | | controlStr = new StringArgument("control", 'J', "control", false, true, |
| | | true, INFO_LDAP_CONTROL_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_CONTROLS.get()); |
| | | controlStr.setPropertyName("control"); |
| | | argParser.addArgument(controlStr); |
| | | |
| | | version = new IntegerArgument("version", OPTION_SHORT_PROTOCOL_VERSION, |
| | | OPTION_LONG_PROTOCOL_VERSION, false, false, true, |
| | | INFO_PROTOCOL_VERSION_PLACEHOLDER.get(), 3, null, |
| | | INFO_DESCRIPTION_VERSION.get()); |
| | | version.setPropertyName(OPTION_LONG_PROTOCOL_VERSION); |
| | | argParser.addArgument(version); |
| | | |
| | | encodingStr = new StringArgument("encoding", 'i', "encoding", false, |
| | | false, true, INFO_ENCODING_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENCODING.get()); |
| | | encodingStr.setPropertyName("encoding"); |
| | | argParser.addArgument(encodingStr); |
| | | |
| | | continueOnError = new BooleanArgument("continueOnError", 'c', |
| | | "continueOnError", INFO_DESCRIPTION_CONTINUE_ON_ERROR.get()); |
| | | continueOnError.setPropertyName("continueOnError"); |
| | | argParser.addArgument(continueOnError); |
| | | |
| | | noop = new BooleanArgument("no-op", OPTION_SHORT_DRYRUN, |
| | | OPTION_LONG_DRYRUN, INFO_DESCRIPTION_NOOP.get()); |
| | | noop.setPropertyName(OPTION_LONG_DRYRUN); |
| | | argParser.addArgument(noop); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = |
| | | connectionFactoryProvider.getAuthenticatedConnectionFactory(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final int versionNumber = version.getIntValue(); |
| | | if (versionNumber != 2 && versionNumber != 3) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String |
| | | .valueOf(versionNumber))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(version |
| | | .getValue()))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final ArrayList<String> dnStrings = new ArrayList<String>(); |
| | | final ArrayList<String> attrAndDNStrings = argParser.getTrailingArguments(); |
| | | |
| | | if (attrAndDNStrings.isEmpty()) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPCOMPARE_NO_ATTR.get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // First element should be an attribute string. |
| | | final String attributeString = attrAndDNStrings.remove(0); |
| | | |
| | | // Rest are DN strings |
| | | for (final String s : attrAndDNStrings) |
| | | { |
| | | dnStrings.add(s); |
| | | } |
| | | |
| | | // If no DNs were provided, then exit with an error. |
| | | if (dnStrings.isEmpty() && (!filename.isPresent())) |
| | | { |
| | | println(ERR_LDAPCOMPARE_NO_DNS.get()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // If trailing DNs were provided and the filename argument was also |
| | | // provided, exit with an error. |
| | | if (!dnStrings.isEmpty() && filename.isPresent()) |
| | | { |
| | | println(ERR_LDAPCOMPARE_FILENAME_AND_DNS.get()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // parse the attribute string |
| | | final int idx = attributeString.indexOf(":"); |
| | | if (idx == -1) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPCOMPARE_INVALID_ATTR_STRING |
| | | .get(attributeString); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | final String attributeType = attributeString.substring(0, idx); |
| | | ByteString attributeVal; |
| | | final String remainder = attributeString.substring(idx + 1, attributeString |
| | | .length()); |
| | | if (remainder.length() > 0) |
| | | { |
| | | final char nextChar = remainder.charAt(0); |
| | | if (nextChar == ':') |
| | | { |
| | | final String base64 = remainder.substring(1, remainder.length()); |
| | | try |
| | | { |
| | | attributeVal = Base64.decode(base64); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException e) |
| | | { |
| | | println(INFO_COMPARE_CANNOT_BASE64_DECODE_ASSERTION_VALUE.get()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | else if (nextChar == '<') |
| | | { |
| | | try |
| | | { |
| | | final String filePath = remainder.substring(1, remainder.length()); |
| | | attributeVal = ByteString.wrap(Utils.readBytesFromFile(filePath)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | println(INFO_COMPARE_CANNOT_READ_ASSERTION_VALUE_FROM_FILE.get(String |
| | | .valueOf(e))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | attributeVal = ByteString.valueOf(remainder); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | attributeVal = ByteString.valueOf(remainder); |
| | | } |
| | | |
| | | final CompareRequest compare = Requests.newCompareRequest("", |
| | | attributeType, attributeVal); |
| | | |
| | | if (controlStr.isPresent()) |
| | | { |
| | | for (final String ctrlString : controlStr.getValues()) |
| | | { |
| | | try |
| | | { |
| | | final Control ctrl = Utils.getControl(ctrlString); |
| | | compare.addControl(ctrl); |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_INVALID_CONTROL_STRING |
| | | .get(ctrlString); |
| | | println(message); |
| | | ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (proxyAuthzID.isPresent()) |
| | | { |
| | | final Control proxyControl = ProxiedAuthV2RequestControl |
| | | .newControl(proxyAuthzID.getValue()); |
| | | compare.addControl(proxyControl); |
| | | } |
| | | |
| | | if (assertionFilter.isPresent()) |
| | | { |
| | | final String filterString = assertionFilter.getValue(); |
| | | Filter filter; |
| | | try |
| | | { |
| | | filter = Filter.valueOf(filterString); |
| | | |
| | | // FIXME -- Change this to the correct OID when the official one |
| | | // is assigned. |
| | | final Control assertionControl = AssertionRequestControl.newControl( |
| | | true, filter); |
| | | compare.addControl(assertionControl); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException le) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_ASSERTION_INVALID_FILTER |
| | | .get(le.getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | BufferedReader rdr = null; |
| | | if (!filename.isPresent() && dnStrings.isEmpty()) |
| | | { |
| | | // Read from stdin. |
| | | rdr = new BufferedReader(new InputStreamReader(System.in)); |
| | | } |
| | | else if (filename.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | rdr = new BufferedReader(new FileReader(filename.getValue())); |
| | | } |
| | | catch (final FileNotFoundException t) |
| | | { |
| | | println(ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), t |
| | | .toString())); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | Connection connection = null; |
| | | if (!noop.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | connection = connectionFactory.getConnection(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | println(LocalizableMessage.raw(ere.getMessage())); |
| | | return ere.getResult().getResultCode().intValue(); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | println(LocalizableMessage.raw(e.getLocalizedMessage())); |
| | | return ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue(); |
| | | } |
| | | } |
| | | |
| | | try |
| | | { |
| | | int result; |
| | | if (rdr == null) |
| | | { |
| | | for (final String dn : dnStrings) |
| | | { |
| | | compare.setName(dn); |
| | | result = executeCompare(compare, connection); |
| | | if (result != 0 && !continueOnError.isPresent()) |
| | | { |
| | | return result; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | String dn; |
| | | try |
| | | { |
| | | while ((dn = rdr.readLine()) != null) |
| | | { |
| | | compare.setName(dn); |
| | | result = executeCompare(compare, connection); |
| | | if (result != 0 && !continueOnError.isPresent()) |
| | | { |
| | | return result; |
| | | } |
| | | } |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | println(ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), |
| | | ioe.toString())); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | if (connection != null) |
| | | { |
| | | connection.close(); |
| | | } |
| | | if (rdr != null) |
| | | { |
| | | try |
| | | { |
| | | rdr.close(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // Just ignore |
| | | } |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.util.Collection; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.StringTokenizer; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.controls.*; |
| | | import org.opends.sdk.ldif.*; |
| | | import org.opends.sdk.requests.AddRequest; |
| | | import org.opends.sdk.requests.DeleteRequest; |
| | | import org.opends.sdk.requests.ModifyDNRequest; |
| | | import org.opends.sdk.requests.ModifyRequest; |
| | | import org.opends.sdk.responses.Responses; |
| | | import org.opends.sdk.responses.Result; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A tool that can be used to issue update (Add/Delete/Modify/ModifyDN) requests |
| | | * to the Directory Server. |
| | | */ |
| | | public final class LDAPModify extends ConsoleApplication |
| | | { |
| | | private class VisitorImpl implements |
| | | ChangeRecordVisitor<Integer, java.lang.Void> |
| | | { |
| | | public Integer visitChangeRecord(final Void aVoid, final AddRequest change) |
| | | { |
| | | for (final Control control : controls) |
| | | { |
| | | change.addControl(control); |
| | | } |
| | | final String opType = "ADD"; |
| | | println(INFO_PROCESSING_OPERATION |
| | | .get(opType, change.getName().toString())); |
| | | if (connection != null) |
| | | { |
| | | try |
| | | { |
| | | Result r; |
| | | try |
| | | { |
| | | r = connection.add(change); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads |
| | | // to interrupt this one. |
| | | r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(r); |
| | | } |
| | | printResult(opType, change.getName().toString(), r); |
| | | return r.getResultCode().intValue(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(LDAPModify.this, ere); |
| | | } |
| | | } |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | public Integer visitChangeRecord(final Void aVoid, |
| | | final DeleteRequest change) |
| | | { |
| | | for (final Control control : controls) |
| | | { |
| | | change.addControl(control); |
| | | } |
| | | final String opType = "DELETE"; |
| | | println(INFO_PROCESSING_OPERATION |
| | | .get(opType, change.getName().toString())); |
| | | if (connection != null) |
| | | { |
| | | try |
| | | { |
| | | Result r; |
| | | try |
| | | { |
| | | r = connection.delete(change); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads |
| | | // to interrupt this one. |
| | | r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(r); |
| | | } |
| | | printResult(opType, change.getName().toString(), r); |
| | | return r.getResultCode().intValue(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(LDAPModify.this, ere); |
| | | } |
| | | } |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | public Integer visitChangeRecord(final Void aVoid, |
| | | final ModifyDNRequest change) |
| | | { |
| | | for (final Control control : controls) |
| | | { |
| | | change.addControl(control); |
| | | } |
| | | final String opType = "MODIFY DN"; |
| | | println(INFO_PROCESSING_OPERATION |
| | | .get(opType, change.getName().toString())); |
| | | if (connection != null) |
| | | { |
| | | try |
| | | { |
| | | Result r; |
| | | try |
| | | { |
| | | r = connection.modifyDN(change); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads |
| | | // to interrupt this one. |
| | | r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(r); |
| | | } |
| | | printResult(opType, change.getName().toString(), r); |
| | | return r.getResultCode().intValue(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(LDAPModify.this, ere); |
| | | } |
| | | } |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | public Integer visitChangeRecord(final Void aVoid, |
| | | final ModifyRequest change) |
| | | { |
| | | for (final Control control : controls) |
| | | { |
| | | change.addControl(control); |
| | | } |
| | | final String opType = "MODIFY"; |
| | | println(INFO_PROCESSING_OPERATION |
| | | .get(opType, change.getName().toString())); |
| | | if (connection != null) |
| | | { |
| | | try |
| | | { |
| | | Result r; |
| | | try |
| | | { |
| | | r = connection.modify(change); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads |
| | | // to interrupt this one. |
| | | r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(r); |
| | | } |
| | | printResult(opType, change.getName().toString(), r); |
| | | return r.getResultCode().intValue(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(LDAPModify.this, ere); |
| | | } |
| | | } |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | private void printResult(final String operationType, final String name, |
| | | final Result r) |
| | | { |
| | | if (r.getResultCode() != ResultCode.SUCCESS |
| | | && r.getResultCode() != ResultCode.REFERRAL) |
| | | { |
| | | final LocalizableMessage msg = INFO_OPERATION_FAILED.get(operationType); |
| | | println(msg); |
| | | println(ERR_TOOL_RESULT_CODE.get(r.getResultCode().intValue(), r |
| | | .getResultCode().toString())); |
| | | if ((r.getDiagnosticMessage() != null) |
| | | && (r.getDiagnosticMessage().length() > 0)) |
| | | { |
| | | println(LocalizableMessage.raw(r.getDiagnosticMessage())); |
| | | } |
| | | if (r.getMatchedDN() != null && r.getMatchedDN().length() > 0) |
| | | { |
| | | println(ERR_TOOL_MATCHED_DN.get(r.getMatchedDN())); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage msg = INFO_OPERATION_SUCCESSFUL.get( |
| | | operationType, name); |
| | | println(msg); |
| | | if ((r.getDiagnosticMessage() != null) |
| | | && (r.getDiagnosticMessage().length() > 0)) |
| | | { |
| | | println(LocalizableMessage.raw(r.getDiagnosticMessage())); |
| | | } |
| | | if (r.getReferralURIs() != null) |
| | | { |
| | | for (final String uri : r.getReferralURIs()) |
| | | { |
| | | println(LocalizableMessage.raw(uri)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | try |
| | | { |
| | | final PreReadResponseControl control = r.getControl( |
| | | PreReadResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | println(INFO_LDAPMODIFY_PREREAD_ENTRY.get()); |
| | | writer.writeEntry(control.getEntry()); |
| | | } |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(de.getLocalizedMessage())); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final PostReadResponseControl control = r.getControl( |
| | | PostReadResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | println(INFO_LDAPMODIFY_POSTREAD_ENTRY.get()); |
| | | writer.writeEntry(control.getEntry()); |
| | | } |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(de.getLocalizedMessage())); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | |
| | | // TODO: CSN control |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The main method for LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainModify(args, System.in, System.out, System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainModify(final String[] args) |
| | | { |
| | | return mainModify(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the LDAPModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. specified, |
| | | * the number of matching entries should be returned or not. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | static int mainModify(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | { |
| | | return new LDAPModify(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private Connection connection; |
| | | |
| | | private EntryWriter writer; |
| | | |
| | | private Collection<Control> controls; |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | |
| | | |
| | | private LDAPModify(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_LDAPMODIFY_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser(LDAPModify.class |
| | | .getName(), toolDescription, false); |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | |
| | | BooleanArgument continueOnError; |
| | | // TODO: Remove this due to new LDIF reader api? |
| | | BooleanArgument defaultAdd; |
| | | BooleanArgument noop; |
| | | BooleanArgument showUsage; |
| | | IntegerArgument version; |
| | | StringArgument assertionFilter; |
| | | StringArgument controlStr; |
| | | StringArgument encodingStr; |
| | | StringArgument filename; |
| | | StringArgument postReadAttributes; |
| | | StringArgument preReadAttributes; |
| | | StringArgument proxyAuthzID; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | |
| | | try |
| | | { |
| | | connectionFactoryProvider = |
| | | new ConnectionFactoryProvider(argParser, this); |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | defaultAdd = new BooleanArgument("defaultAdd", 'a', "defaultAdd", |
| | | INFO_MODIFY_DESCRIPTION_DEFAULT_ADD.get()); |
| | | argParser.addArgument(defaultAdd); |
| | | |
| | | filename = new StringArgument("filename", OPTION_SHORT_FILENAME, |
| | | OPTION_LONG_FILENAME, false, false, true, |
| | | INFO_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_LDAPMODIFY_DESCRIPTION_FILENAME.get()); |
| | | filename.setPropertyName(OPTION_LONG_FILENAME); |
| | | argParser.addArgument(filename); |
| | | |
| | | proxyAuthzID = new StringArgument("proxy_authzid", |
| | | OPTION_SHORT_PROXYAUTHID, OPTION_LONG_PROXYAUTHID, false, false, |
| | | true, INFO_PROXYAUTHID_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROXY_AUTHZID.get()); |
| | | proxyAuthzID.setPropertyName(OPTION_LONG_PROXYAUTHID); |
| | | argParser.addArgument(proxyAuthzID); |
| | | |
| | | assertionFilter = new StringArgument("assertionfilter", null, |
| | | OPTION_LONG_ASSERTION_FILE, false, false, true, |
| | | INFO_ASSERTION_FILTER_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ASSERTION_FILTER.get()); |
| | | assertionFilter.setPropertyName(OPTION_LONG_ASSERTION_FILE); |
| | | argParser.addArgument(assertionFilter); |
| | | |
| | | preReadAttributes = new StringArgument("prereadattrs", null, |
| | | "preReadAttributes", false, false, true, |
| | | INFO_ATTRIBUTE_LIST_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PREREAD_ATTRS.get()); |
| | | preReadAttributes.setPropertyName("preReadAttributes"); |
| | | argParser.addArgument(preReadAttributes); |
| | | |
| | | postReadAttributes = new StringArgument("postreadattrs", null, |
| | | "postReadAttributes", false, false, true, |
| | | INFO_ATTRIBUTE_LIST_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_POSTREAD_ATTRS.get()); |
| | | postReadAttributes.setPropertyName("postReadAttributes"); |
| | | argParser.addArgument(postReadAttributes); |
| | | |
| | | controlStr = new StringArgument("control", 'J', "control", false, true, |
| | | true, INFO_LDAP_CONTROL_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_CONTROLS.get()); |
| | | controlStr.setPropertyName("control"); |
| | | argParser.addArgument(controlStr); |
| | | |
| | | version = new IntegerArgument("version", OPTION_SHORT_PROTOCOL_VERSION, |
| | | OPTION_LONG_PROTOCOL_VERSION, false, false, true, |
| | | INFO_PROTOCOL_VERSION_PLACEHOLDER.get(), 3, null, |
| | | INFO_DESCRIPTION_VERSION.get()); |
| | | version.setPropertyName(OPTION_LONG_PROTOCOL_VERSION); |
| | | argParser.addArgument(version); |
| | | |
| | | encodingStr = new StringArgument("encoding", 'i', "encoding", false, |
| | | false, true, INFO_ENCODING_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ENCODING.get()); |
| | | encodingStr.setPropertyName("encoding"); |
| | | argParser.addArgument(encodingStr); |
| | | |
| | | continueOnError = new BooleanArgument("continueOnError", 'c', |
| | | "continueOnError", INFO_DESCRIPTION_CONTINUE_ON_ERROR.get()); |
| | | continueOnError.setPropertyName("continueOnError"); |
| | | argParser.addArgument(continueOnError); |
| | | |
| | | noop = new BooleanArgument("no-op", OPTION_SHORT_DRYRUN, |
| | | OPTION_LONG_DRYRUN, INFO_DESCRIPTION_NOOP.get()); |
| | | noop.setPropertyName(OPTION_LONG_DRYRUN); |
| | | argParser.addArgument(noop); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = |
| | | connectionFactoryProvider.getAuthenticatedConnectionFactory(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final int versionNumber = version.getIntValue(); |
| | | if (versionNumber != 2 && versionNumber != 3) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String |
| | | .valueOf(versionNumber))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(version |
| | | .getValue()))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // modifyOptions.setShowOperations(noop.isPresent()); |
| | | // modifyOptions.setVerbose(verbose.isPresent()); |
| | | // modifyOptions.setContinueOnError(continueOnError.isPresent()); |
| | | // modifyOptions.setEncoding(encodingStr.getValue()); |
| | | // modifyOptions.setDefaultAdd(defaultAdd.isPresent()); |
| | | |
| | | controls = new LinkedList<Control>(); |
| | | if (controlStr.isPresent()) |
| | | { |
| | | for (final String ctrlString : controlStr.getValues()) |
| | | { |
| | | try |
| | | { |
| | | final Control ctrl = Utils.getControl(ctrlString); |
| | | controls.add(ctrl); |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_INVALID_CONTROL_STRING |
| | | .get(ctrlString); |
| | | println(message); |
| | | ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (proxyAuthzID.isPresent()) |
| | | { |
| | | final Control proxyControl = ProxiedAuthV2RequestControl |
| | | .newControl(proxyAuthzID.getValue()); |
| | | controls.add(proxyControl); |
| | | } |
| | | |
| | | if (assertionFilter.isPresent()) |
| | | { |
| | | final String filterString = assertionFilter.getValue(); |
| | | Filter filter; |
| | | try |
| | | { |
| | | filter = Filter.valueOf(filterString); |
| | | |
| | | // FIXME -- Change this to the correct OID when the official one |
| | | // is assigned. |
| | | final Control assertionControl = AssertionRequestControl.newControl( |
| | | true, filter); |
| | | controls.add(assertionControl); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException le) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_ASSERTION_INVALID_FILTER |
| | | .get(le.getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | if (preReadAttributes.isPresent()) |
| | | { |
| | | final String valueStr = preReadAttributes.getValue(); |
| | | final StringTokenizer tokenizer = new StringTokenizer(valueStr, ", "); |
| | | final List<String> attributes = new LinkedList<String>(); |
| | | while (tokenizer.hasMoreTokens()) |
| | | { |
| | | attributes.add(tokenizer.nextToken()); |
| | | } |
| | | final PreReadRequestControl control = PreReadRequestControl.newControl( |
| | | true, attributes); |
| | | controls.add(control); |
| | | } |
| | | |
| | | if (postReadAttributes.isPresent()) |
| | | { |
| | | final String valueStr = postReadAttributes.getValue(); |
| | | final StringTokenizer tokenizer = new StringTokenizer(valueStr, ", "); |
| | | final List<String> attributes = new LinkedList<String>(); |
| | | while (tokenizer.hasMoreTokens()) |
| | | { |
| | | attributes.add(tokenizer.nextToken()); |
| | | } |
| | | final PostReadRequestControl control = PostReadRequestControl.newControl( |
| | | true, attributes); |
| | | controls.add(control); |
| | | } |
| | | |
| | | if (!noop.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | connection = connectionFactory.getConnection(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(this, ere); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | println(LocalizableMessage.raw(e.getLocalizedMessage())); |
| | | return ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue(); |
| | | } |
| | | } |
| | | |
| | | Utils.printPasswordPolicyResults(this, connection); |
| | | |
| | | writer = new LDIFEntryWriter(getOutputStream()); |
| | | final VisitorImpl visitor = new VisitorImpl(); |
| | | try |
| | | { |
| | | ChangeRecordReader reader; |
| | | if (filename.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | reader = new LDIFChangeRecordReader(new FileInputStream(filename |
| | | .getValue())); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ |
| | | .get(filename.getValue(), e.getLocalizedMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | reader = new LDIFChangeRecordReader(getInputStream()); |
| | | } |
| | | |
| | | try |
| | | { |
| | | while (reader.hasNext()) |
| | | { |
| | | final ChangeRecord cr = reader.readChangeRecord(); |
| | | final int result = cr.accept(visitor, null); |
| | | if (result != 0 && !continueOnError.isPresent()) |
| | | { |
| | | return result; |
| | | } |
| | | } |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | final LocalizableMessage message = ERR_LDIF_FILE_READ_ERROR.get( |
| | | filename.getValue(), ioe.getLocalizedMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue(); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | if (connection != null) |
| | | { |
| | | connection.close(); |
| | | } |
| | | } |
| | | |
| | | return ResultCode.SUCCESS.intValue(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.requests.PasswordModifyExtendedRequest; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.responses.PasswordModifyExtendedResult; |
| | | import org.opends.sdk.responses.Responses; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A tool that can be used to issue LDAP password modify extended requests to |
| | | * the Directory Server. It exposes the three primary options available for this |
| | | * operation, which are: |
| | | * <UL> |
| | | * <LI>The user identity whose password should be changed.</LI> |
| | | * <LI>The current password for the user.</LI> |
| | | * <LI>The new password for the user. |
| | | * </UL> |
| | | * All of these are optional components that may be included or omitted from the |
| | | * request. |
| | | */ |
| | | public final class LDAPPasswordModify extends ConsoleApplication |
| | | { |
| | | /** |
| | | * Parses the command-line arguments, establishes a connection to the |
| | | * Directory Server, sends the password modify request, and reads the |
| | | * response. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainPasswordModify(args, System.in, System.out, |
| | | System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the command-line arguments, establishes a connection to the |
| | | * Directory Server, sends the password modify request, and reads the |
| | | * response. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return An integer value of zero if everything completed successfully, or a |
| | | * nonzero value if an error occurred. |
| | | */ |
| | | static int mainPasswordModify(final String[] args) |
| | | { |
| | | return mainPasswordModify(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the LDAPPasswordModify tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. specified, |
| | | * the number of matching entries should be returned or not. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | static int mainPasswordModify(final String[] args, |
| | | final InputStream inStream, final OutputStream outStream, |
| | | final OutputStream errStream) |
| | | { |
| | | return new LDAPPasswordModify(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | |
| | | |
| | | private LDAPPasswordModify(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_LDAPPWMOD_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser( |
| | | LDAPPasswordModify.class.getName(), toolDescription, false); |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | |
| | | FileBasedArgument currentPWFile; |
| | | FileBasedArgument newPWFile; |
| | | BooleanArgument showUsage; |
| | | IntegerArgument version; |
| | | StringArgument currentPW; |
| | | StringArgument controlStr; |
| | | StringArgument newPW; |
| | | StringArgument proxyAuthzID; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | |
| | | try |
| | | { |
| | | connectionFactoryProvider = |
| | | new ConnectionFactoryProvider(argParser, this); |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | newPW = new StringArgument("newpw", 'n', "newPassword", false, false, |
| | | true, INFO_NEW_PASSWORD_PLACEHOLDER.get(), null, null, |
| | | INFO_LDAPPWMOD_DESCRIPTION_NEWPW.get()); |
| | | newPW.setPropertyName("newPassword"); |
| | | argParser.addArgument(newPW); |
| | | |
| | | newPWFile = new FileBasedArgument("newpwfile", 'F', "newPasswordFile", |
| | | false, false, INFO_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_LDAPPWMOD_DESCRIPTION_NEWPWFILE.get()); |
| | | newPWFile.setPropertyName("newPasswordFile"); |
| | | argParser.addArgument(newPWFile); |
| | | |
| | | currentPW = new StringArgument("currentpw", 'c', "currentPassword", |
| | | false, false, true, INFO_CURRENT_PASSWORD_PLACEHOLDER.get(), null, |
| | | null, INFO_LDAPPWMOD_DESCRIPTION_CURRENTPW.get()); |
| | | currentPW.setPropertyName("currentPassword"); |
| | | argParser.addArgument(currentPW); |
| | | |
| | | currentPWFile = new FileBasedArgument("currentpwfile", 'C', |
| | | "currentPasswordFile", false, false, INFO_FILE_PLACEHOLDER.get(), |
| | | null, null, INFO_LDAPPWMOD_DESCRIPTION_CURRENTPWFILE.get()); |
| | | currentPWFile.setPropertyName("currentPasswordFile"); |
| | | argParser.addArgument(currentPWFile); |
| | | |
| | | proxyAuthzID = new StringArgument("authzid", 'a', "authzID", false, |
| | | false, true, INFO_PROXYAUTHID_PLACEHOLDER.get(), null, null, |
| | | INFO_LDAPPWMOD_DESCRIPTION_AUTHZID.get()); |
| | | proxyAuthzID.setPropertyName("authzID"); |
| | | argParser.addArgument(proxyAuthzID); |
| | | |
| | | controlStr = new StringArgument("control", 'J', "control", false, true, |
| | | true, INFO_LDAP_CONTROL_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_CONTROLS.get()); |
| | | controlStr.setPropertyName("control"); |
| | | argParser.addArgument(controlStr); |
| | | |
| | | version = new IntegerArgument("version", OPTION_SHORT_PROTOCOL_VERSION, |
| | | OPTION_LONG_PROTOCOL_VERSION, false, false, true, |
| | | INFO_PROTOCOL_VERSION_PLACEHOLDER.get(), 3, null, |
| | | INFO_DESCRIPTION_VERSION.get()); |
| | | version.setPropertyName(OPTION_LONG_PROTOCOL_VERSION); |
| | | argParser.addArgument(version); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = |
| | | connectionFactoryProvider.getAuthenticatedConnectionFactory(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final PasswordModifyExtendedRequest request = Requests |
| | | .newPasswordModifyExtendedRequest(); |
| | | try |
| | | { |
| | | final int versionNumber = version.getIntValue(); |
| | | if (versionNumber != 2 && versionNumber != 3) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String |
| | | .valueOf(versionNumber))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(version |
| | | .getValue()))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | if (controlStr.isPresent()) |
| | | { |
| | | for (final String ctrlString : controlStr.getValues()) |
| | | { |
| | | try |
| | | { |
| | | final Control ctrl = Utils.getControl(ctrlString); |
| | | request.addControl(ctrl); |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_INVALID_CONTROL_STRING |
| | | .get(ctrlString); |
| | | println(message); |
| | | ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (newPW.isPresent() && newPWFile.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( |
| | | newPW.getLongIdentifier(), newPWFile.getLongIdentifier()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | if (currentPW.isPresent() && currentPWFile.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( |
| | | currentPW.getLongIdentifier(), currentPWFile.getLongIdentifier()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | Connection connection; |
| | | try |
| | | { |
| | | connection = connectionFactory.getConnection(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(this, ere); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | println(LocalizableMessage.raw(e.getLocalizedMessage())); |
| | | return ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue(); |
| | | } |
| | | |
| | | if (proxyAuthzID.isPresent()) |
| | | { |
| | | request.setUserIdentity(proxyAuthzID.getValue()); |
| | | } |
| | | |
| | | if (currentPW.isPresent()) |
| | | { |
| | | request.setOldPassword(ByteString.valueOf(currentPW.getValue())); |
| | | } |
| | | else if (currentPWFile.isPresent()) |
| | | { |
| | | request.setOldPassword(ByteString.valueOf(currentPWFile.getValue())); |
| | | } |
| | | |
| | | if (newPW.isPresent()) |
| | | { |
| | | request.setNewPassword(ByteString.valueOf(newPW.getValue())); |
| | | } |
| | | else if (newPWFile.isPresent()) |
| | | { |
| | | request.setNewPassword(ByteString.valueOf(newPWFile.getValue())); |
| | | } |
| | | |
| | | PasswordModifyExtendedResult result; |
| | | try |
| | | { |
| | | try |
| | | { |
| | | result = connection.extendedRequest(request); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | result = Responses.newPasswordModifyExtendedResult( |
| | | ResultCode.CLIENT_SIDE_USER_CANCELLED).setCause(e) |
| | | .setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(result); |
| | | } |
| | | } |
| | | catch (final ErrorResultException e) |
| | | { |
| | | LocalizableMessage message = ERR_LDAPPWMOD_FAILED |
| | | .get(e.getResult().getResultCode().intValue(), e.getResult() |
| | | .getResultCode().toString()); |
| | | println(message); |
| | | |
| | | final String errorMessage = e.getResult().getDiagnosticMessage(); |
| | | if ((errorMessage != null) && (errorMessage.length() > 0)) |
| | | { |
| | | message = ERR_LDAPPWMOD_FAILURE_ERROR_MESSAGE.get(errorMessage); |
| | | println(message); |
| | | } |
| | | |
| | | final String matchedDN = e.getResult().getMatchedDN(); |
| | | if (matchedDN != null && matchedDN.length() > 0) |
| | | { |
| | | message = ERR_LDAPPWMOD_FAILURE_MATCHED_DN.get(matchedDN); |
| | | println(message); |
| | | } |
| | | return e.getResult().getResultCode().intValue(); |
| | | } |
| | | |
| | | LocalizableMessage message = INFO_LDAPPWMOD_SUCCESSFUL.get(); |
| | | println(message); |
| | | |
| | | final String additionalInfo = result.getDiagnosticMessage(); |
| | | if ((additionalInfo != null) && (additionalInfo.length() > 0)) |
| | | { |
| | | |
| | | message = INFO_LDAPPWMOD_ADDITIONAL_INFO.get(additionalInfo); |
| | | println(message); |
| | | } |
| | | |
| | | if (result.getGeneratedPassword() != null) |
| | | { |
| | | message = INFO_LDAPPWMOD_GENERATED_PASSWORD.get(result |
| | | .getGeneratedPassword().toString()); |
| | | println(message); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.*; |
| | | import java.util.*; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.controls.*; |
| | | import org.opends.sdk.ldif.EntryWriter; |
| | | import org.opends.sdk.ldif.LDIFEntryWriter; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.requests.SearchRequest; |
| | | import org.opends.sdk.responses.Responses; |
| | | import org.opends.sdk.responses.Result; |
| | | import org.opends.sdk.responses.SearchResultEntry; |
| | | import org.opends.sdk.responses.SearchResultReference; |
| | | |
| | | import com.sun.opends.sdk.controls.AccountUsabilityResponseControl; |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A tool that can be used to issue Search requests to the Directory Server. |
| | | */ |
| | | public final class LDAPSearch extends ConsoleApplication |
| | | { |
| | | private class LDAPSearchResultHandler implements SearchResultHandler |
| | | { |
| | | private int entryCount = 0; |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean handleEntry(final SearchResultEntry entry) |
| | | { |
| | | entryCount++; |
| | | |
| | | try |
| | | { |
| | | final EntryChangeNotificationResponseControl control = entry |
| | | .getControl(EntryChangeNotificationResponseControl.DECODER, |
| | | new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | println(INFO_LDAPSEARCH_PSEARCH_CHANGE_TYPE.get(control |
| | | .getChangeType().toString())); |
| | | final DN previousDN = control.getPreviousName(); |
| | | if (previousDN != null) |
| | | { |
| | | println(INFO_LDAPSEARCH_PSEARCH_PREVIOUS_DN.get(previousDN |
| | | .toString())); |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(de.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final AccountUsabilityResponseControl control = entry.getControl( |
| | | AccountUsabilityResponseControl.DECODER, new DecodeOptions()); |
| | | |
| | | if (control != null) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_HEADER.get()); |
| | | if (control.isUsable()) |
| | | { |
| | | |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_IS_USABLE.get()); |
| | | if (control.getSecondsBeforeExpiration() > 0) |
| | | { |
| | | final int timeToExp = control.getSecondsBeforeExpiration(); |
| | | final LocalizableMessage timeToExpStr = Utils |
| | | .secondsToTimeString(timeToExp); |
| | | |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_EXPIRATION |
| | | .get(timeToExpStr)); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_NOT_USABLE.get()); |
| | | if (control.isInactive()) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_ACCT_INACTIVE.get()); |
| | | } |
| | | if (control.isReset()) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_PW_RESET.get()); |
| | | } |
| | | if (control.isExpired()) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_PW_EXPIRED.get()); |
| | | |
| | | if (control.getRemainingGraceLogins() > 0) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_REMAINING_GRACE.get(control |
| | | .getRemainingGraceLogins())); |
| | | } |
| | | } |
| | | if (control.isLocked()) |
| | | { |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_LOCKED.get()); |
| | | if (control.getSecondsBeforeUnlock() > 0) |
| | | { |
| | | final int timeToUnlock = control.getSecondsBeforeUnlock(); |
| | | final LocalizableMessage timeToUnlockStr = Utils |
| | | .secondsToTimeString(timeToUnlock); |
| | | |
| | | println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK |
| | | .get(timeToUnlockStr)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(de.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | ldifWriter.writeEntry(entry); |
| | | ldifWriter.flush(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // Something is seriously wrong |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean handleReference(final SearchResultReference reference) |
| | | { |
| | | println(LocalizableMessage.raw(reference.toString())); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void handleErrorResult(ErrorResultException error) |
| | | { |
| | | // Ignore. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void handleResult(Result result) |
| | | { |
| | | // Ignore. |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The main method for LDAPSearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainSearch(args, false, System.in, System.out, |
| | | System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the ldapsearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainSearch(final String[] args) |
| | | { |
| | | return mainSearch(args, true, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the ldapsearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @param returnMatchingEntries |
| | | * whether when the option --countEntries is specified, the number of |
| | | * matching entries should be returned or not. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainSearch(final String[] args, |
| | | final boolean returnMatchingEntries, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | { |
| | | return new LDAPSearch(inStream, outStream, errStream).run(args, |
| | | returnMatchingEntries); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the ldapsearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | static int mainSearch(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | { |
| | | return mainSearch(args, true, inStream, outStream, errStream); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | private EntryWriter ldifWriter; |
| | | |
| | | |
| | | |
| | | private LDAPSearch(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args, final boolean returnMatchingEntries) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_LDAPSEARCH_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser(LDAPSearch.class |
| | | .getName(), toolDescription, false, true, 0, 0, |
| | | "[filter] [attributes ...]"); |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | |
| | | BooleanArgument countEntries; |
| | | BooleanArgument dontWrap; |
| | | BooleanArgument noop; |
| | | BooleanArgument typesOnly; |
| | | IntegerArgument simplePageSize; |
| | | IntegerArgument timeLimit; |
| | | IntegerArgument version; |
| | | StringArgument baseDN; |
| | | StringArgument controlStr; |
| | | MultiChoiceArgument<DereferenceAliasesPolicy> dereferencePolicy; |
| | | StringArgument filename; |
| | | StringArgument matchedValuesFilter; |
| | | StringArgument pSearchInfo; |
| | | MultiChoiceArgument<SearchScope> searchScope; |
| | | StringArgument vlvDescriptor; |
| | | StringArgument effectiveRightsUser; |
| | | StringArgument effectiveRightsAttrs; |
| | | StringArgument sortOrder; |
| | | StringArgument proxyAuthzID; |
| | | StringArgument assertionFilter; |
| | | IntegerArgument sizeLimit; |
| | | try |
| | | { |
| | | connectionFactoryProvider = |
| | | new ConnectionFactoryProvider(argParser, this); |
| | | final StringArgument propertiesFileArgument = new StringArgument( |
| | | "propertiesFilePath", null, OPTION_LONG_PROP_FILE_PATH, false, false, |
| | | true, INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | final BooleanArgument noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | baseDN = new StringArgument("baseDN", OPTION_SHORT_BASEDN, |
| | | OPTION_LONG_BASEDN, true, false, true, INFO_BASEDN_PLACEHOLDER.get(), |
| | | null, null, INFO_SEARCH_DESCRIPTION_BASEDN.get()); |
| | | baseDN.setPropertyName(OPTION_LONG_BASEDN); |
| | | argParser.addArgument(baseDN); |
| | | |
| | | searchScope = new MultiChoiceArgument<SearchScope>("searchScope", 's', |
| | | "searchScope", false, true, INFO_SEARCH_SCOPE_PLACEHOLDER.get(), |
| | | SearchScope.values(), false, INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE |
| | | .get()); |
| | | searchScope.setPropertyName("searchScope"); |
| | | searchScope.setDefaultValue(SearchScope.WHOLE_SUBTREE); |
| | | argParser.addArgument(searchScope); |
| | | |
| | | filename = new StringArgument("filename", OPTION_SHORT_FILENAME, |
| | | OPTION_LONG_FILENAME, false, false, true, |
| | | INFO_FILE_PLACEHOLDER.get(), null, null, |
| | | INFO_SEARCH_DESCRIPTION_FILENAME.get()); |
| | | searchScope.setPropertyName(OPTION_LONG_FILENAME); |
| | | argParser.addArgument(filename); |
| | | |
| | | proxyAuthzID = new StringArgument("proxy_authzid", |
| | | OPTION_SHORT_PROXYAUTHID, OPTION_LONG_PROXYAUTHID, false, false, |
| | | true, INFO_PROXYAUTHID_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROXY_AUTHZID.get()); |
| | | proxyAuthzID.setPropertyName(OPTION_LONG_PROXYAUTHID); |
| | | argParser.addArgument(proxyAuthzID); |
| | | |
| | | pSearchInfo = new StringArgument("psearchinfo", 'C', "persistentSearch", |
| | | false, false, true, INFO_PSEARCH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PSEARCH_INFO.get()); |
| | | pSearchInfo.setPropertyName("persistentSearch"); |
| | | argParser.addArgument(pSearchInfo); |
| | | |
| | | simplePageSize = new IntegerArgument("simplepagesize", null, |
| | | "simplePageSize", false, false, true, INFO_NUM_ENTRIES_PLACEHOLDER |
| | | .get(), 1000, null, true, 1, false, 0, |
| | | INFO_DESCRIPTION_SIMPLE_PAGE_SIZE.get()); |
| | | simplePageSize.setPropertyName("simplePageSize"); |
| | | argParser.addArgument(simplePageSize); |
| | | |
| | | assertionFilter = new StringArgument("assertionfilter", null, |
| | | OPTION_LONG_ASSERTION_FILE, false, false, true, |
| | | INFO_ASSERTION_FILTER_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_ASSERTION_FILTER.get()); |
| | | assertionFilter.setPropertyName(OPTION_LONG_ASSERTION_FILE); |
| | | argParser.addArgument(assertionFilter); |
| | | |
| | | matchedValuesFilter = new StringArgument("matchedvalues", null, |
| | | "matchedValuesFilter", false, true, true, INFO_FILTER_PLACEHOLDER |
| | | .get(), null, null, INFO_DESCRIPTION_MATCHED_VALUES_FILTER.get()); |
| | | matchedValuesFilter.setPropertyName("matchedValuesFilter"); |
| | | argParser.addArgument(matchedValuesFilter); |
| | | |
| | | sortOrder = new StringArgument("sortorder", 'S', "sortOrder", false, |
| | | false, true, INFO_SORT_ORDER_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_SORT_ORDER.get()); |
| | | sortOrder.setPropertyName("sortOrder"); |
| | | argParser.addArgument(sortOrder); |
| | | |
| | | vlvDescriptor = new StringArgument("vlvdescriptor", 'G', |
| | | "virtualListView", false, false, true, INFO_VLV_PLACEHOLDER.get(), |
| | | null, null, INFO_DESCRIPTION_VLV.get()); |
| | | vlvDescriptor.setPropertyName("virtualListView"); |
| | | argParser.addArgument(vlvDescriptor); |
| | | |
| | | controlStr = new StringArgument("control", 'J', "control", false, true, |
| | | true, INFO_LDAP_CONTROL_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_CONTROLS.get()); |
| | | controlStr.setPropertyName("control"); |
| | | argParser.addArgument(controlStr); |
| | | |
| | | effectiveRightsUser = new StringArgument("effectiveRightsUser", |
| | | OPTION_SHORT_EFFECTIVERIGHTSUSER, OPTION_LONG_EFFECTIVERIGHTSUSER, |
| | | false, false, true, INFO_PROXYAUTHID_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_EFFECTIVERIGHTS_USER.get()); |
| | | effectiveRightsUser.setPropertyName(OPTION_LONG_EFFECTIVERIGHTSUSER); |
| | | argParser.addArgument(effectiveRightsUser); |
| | | |
| | | effectiveRightsAttrs = new StringArgument("effectiveRightsAttrs", |
| | | OPTION_SHORT_EFFECTIVERIGHTSATTR, OPTION_LONG_EFFECTIVERIGHTSATTR, |
| | | false, true, true, INFO_ATTRIBUTE_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_EFFECTIVERIGHTS_ATTR.get()); |
| | | effectiveRightsAttrs.setPropertyName(OPTION_LONG_EFFECTIVERIGHTSATTR); |
| | | argParser.addArgument(effectiveRightsAttrs); |
| | | |
| | | version = new IntegerArgument("version", OPTION_SHORT_PROTOCOL_VERSION, |
| | | OPTION_LONG_PROTOCOL_VERSION, false, false, true, |
| | | INFO_PROTOCOL_VERSION_PLACEHOLDER.get(), 3, null, |
| | | INFO_DESCRIPTION_VERSION.get()); |
| | | version.setPropertyName(OPTION_LONG_PROTOCOL_VERSION); |
| | | argParser.addArgument(version); |
| | | |
| | | final StringArgument encodingStr = new StringArgument("encoding", 'i', |
| | | "encoding", false, false, true, INFO_ENCODING_PLACEHOLDER.get(), |
| | | null, null, INFO_DESCRIPTION_ENCODING.get()); |
| | | encodingStr.setPropertyName("encoding"); |
| | | argParser.addArgument(encodingStr); |
| | | |
| | | dereferencePolicy = new MultiChoiceArgument<DereferenceAliasesPolicy>( |
| | | "derefpolicy", 'a', "dereferencePolicy", false, true, |
| | | INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(), DereferenceAliasesPolicy |
| | | .values(), false, INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY |
| | | .get()); |
| | | dereferencePolicy.setPropertyName("dereferencePolicy"); |
| | | dereferencePolicy.setDefaultValue(DereferenceAliasesPolicy.NEVER); |
| | | argParser.addArgument(dereferencePolicy); |
| | | |
| | | typesOnly = new BooleanArgument("typesOnly", 'A', "typesOnly", |
| | | INFO_DESCRIPTION_TYPES_ONLY.get()); |
| | | typesOnly.setPropertyName("typesOnly"); |
| | | argParser.addArgument(typesOnly); |
| | | |
| | | sizeLimit = new IntegerArgument("sizeLimit", 'z', "sizeLimit", false, |
| | | false, true, INFO_SIZE_LIMIT_PLACEHOLDER.get(), 0, null, |
| | | INFO_SEARCH_DESCRIPTION_SIZE_LIMIT.get()); |
| | | sizeLimit.setPropertyName("sizeLimit"); |
| | | argParser.addArgument(sizeLimit); |
| | | |
| | | timeLimit = new IntegerArgument("timeLimit", 'l', "timeLimit", false, |
| | | false, true, INFO_TIME_LIMIT_PLACEHOLDER.get(), 0, null, |
| | | INFO_SEARCH_DESCRIPTION_TIME_LIMIT.get()); |
| | | timeLimit.setPropertyName("timeLimit"); |
| | | argParser.addArgument(timeLimit); |
| | | |
| | | dontWrap = new BooleanArgument("dontwrap", 't', "dontWrap", |
| | | INFO_DESCRIPTION_DONT_WRAP.get()); |
| | | dontWrap.setPropertyName("dontWrap"); |
| | | argParser.addArgument(dontWrap); |
| | | |
| | | countEntries = new BooleanArgument("countentries", null, "countEntries", |
| | | INFO_DESCRIPTION_COUNT_ENTRIES.get()); |
| | | countEntries.setPropertyName("countEntries"); |
| | | argParser.addArgument(countEntries); |
| | | |
| | | final BooleanArgument continueOnError = new BooleanArgument( |
| | | "continueOnError", 'c', "continueOnError", |
| | | INFO_DESCRIPTION_CONTINUE_ON_ERROR.get()); |
| | | continueOnError.setPropertyName("continueOnError"); |
| | | argParser.addArgument(continueOnError); |
| | | |
| | | noop = new BooleanArgument("noop", OPTION_SHORT_DRYRUN, |
| | | OPTION_LONG_DRYRUN, INFO_DESCRIPTION_NOOP.get()); |
| | | noop.setPropertyName(OPTION_LONG_DRYRUN); |
| | | argParser.addArgument(noop); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | final BooleanArgument showUsage = new BooleanArgument("showUsage", |
| | | OPTION_SHORT_HELP, OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = |
| | | connectionFactoryProvider.getAuthenticatedConnectionFactory(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final List<Filter> filters = new LinkedList<Filter>(); |
| | | final List<String> attributes = new LinkedList<String>(); |
| | | final ArrayList<String> filterAndAttributeStrings = argParser |
| | | .getTrailingArguments(); |
| | | if (filterAndAttributeStrings.size() > 0) |
| | | { |
| | | // the list of trailing arguments should be structured as follow: |
| | | // - If a filter file is present, trailing arguments are |
| | | // considered as attributes |
| | | // - If filter file is not present, the first trailing argument is |
| | | // considered the filter, the other as attributes. |
| | | if (!filename.isPresent()) |
| | | { |
| | | final String filterString = filterAndAttributeStrings.remove(0); |
| | | |
| | | try |
| | | { |
| | | filters.add(Filter.valueOf(filterString)); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException e) |
| | | { |
| | | println(e.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); |
| | | } |
| | | } |
| | | // The rest are attributes |
| | | for (final String s : filterAndAttributeStrings) |
| | | { |
| | | attributes.add(s); |
| | | } |
| | | } |
| | | |
| | | if (filename.isPresent()) |
| | | { |
| | | // Read the filter strings. |
| | | BufferedReader in = null; |
| | | try |
| | | { |
| | | in = new BufferedReader(new FileReader(filename.getValue())); |
| | | String line = null; |
| | | |
| | | while ((line = in.readLine()) != null) |
| | | { |
| | | if (line.trim().equals("")) |
| | | { |
| | | // ignore empty lines. |
| | | continue; |
| | | } |
| | | final Filter ldapFilter = Filter.valueOf(line); |
| | | filters.add(ldapFilter); |
| | | } |
| | | } |
| | | catch (final LocalizedIllegalArgumentException e) |
| | | { |
| | | println(e.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); |
| | | } |
| | | catch (final IOException e) |
| | | { |
| | | println(LocalizableMessage.raw(e.toString())); |
| | | return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); |
| | | } |
| | | finally |
| | | { |
| | | if (in != null) |
| | | { |
| | | try |
| | | { |
| | | in.close(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (filters.isEmpty()) |
| | | { |
| | | println(ERR_SEARCH_NO_FILTERS.get()); |
| | | println(argParser.getUsageMessage()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | SearchScope scope; |
| | | try |
| | | { |
| | | scope = searchScope.getTypedValue(); |
| | | } |
| | | catch (final ArgumentException ex1) |
| | | { |
| | | println(ex1.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | SearchRequest search; |
| | | try |
| | | { |
| | | search = Requests.newSearchRequest(DN.valueOf(baseDN.getValue()), scope, |
| | | filters.get(0), attributes.toArray(new String[attributes.size()])); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException e) |
| | | { |
| | | println(e.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Read the LDAP version number. |
| | | try |
| | | { |
| | | final int versionNumber = version.getIntValue(); |
| | | if (versionNumber != 2 && versionNumber != 3) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String |
| | | .valueOf(versionNumber))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | println(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(version |
| | | .getValue()))); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | search.setTypesOnly(typesOnly.isPresent()); |
| | | // searchOptions.setShowOperations(noop.isPresent()); |
| | | // searchOptions.setVerbose(verbose.isPresent()); |
| | | // searchOptions.setContinueOnError(continueOnError.isPresent()); |
| | | // searchOptions.setEncoding(encodingStr.getValue()); |
| | | // searchOptions.setCountMatchingEntries(countEntries.isPresent()); |
| | | try |
| | | { |
| | | search.setTimeLimit(timeLimit.getIntValue()); |
| | | search.setSizeLimit(sizeLimit.getIntValue()); |
| | | } |
| | | catch (final ArgumentException ex1) |
| | | { |
| | | println(ex1.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | try |
| | | { |
| | | search.setDereferenceAliasesPolicy(dereferencePolicy.getTypedValue()); |
| | | } |
| | | catch (final ArgumentException ex1) |
| | | { |
| | | println(ex1.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | if (controlStr.isPresent()) |
| | | { |
| | | for (final String ctrlString : controlStr.getValues()) |
| | | { |
| | | try |
| | | { |
| | | final Control ctrl = Utils.getControl(ctrlString); |
| | | search.addControl(ctrl); |
| | | } |
| | | catch (final DecodeException de) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_INVALID_CONTROL_STRING |
| | | .get(ctrlString); |
| | | println(message); |
| | | ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (effectiveRightsUser.isPresent()) |
| | | { |
| | | final String authzID = effectiveRightsUser.getValue(); |
| | | if (!authzID.startsWith("dn:")) |
| | | { |
| | | final LocalizableMessage message = ERR_EFFECTIVERIGHTS_INVALID_AUTHZID |
| | | .get(authzID); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | final Control effectiveRightsControl = GetEffectiveRightsRequestControl |
| | | .newControl(false, authzID.substring(3), effectiveRightsAttrs |
| | | .getValues().toArray( |
| | | new String[effectiveRightsAttrs.getValues().size()])); |
| | | search.addControl(effectiveRightsControl); |
| | | } |
| | | |
| | | if (proxyAuthzID.isPresent()) |
| | | { |
| | | final Control proxyControl = ProxiedAuthV2RequestControl |
| | | .newControl(proxyAuthzID.getValue()); |
| | | search.addControl(proxyControl); |
| | | } |
| | | |
| | | if (pSearchInfo.isPresent()) |
| | | { |
| | | final String infoString = StaticUtils.toLowerCase(pSearchInfo.getValue() |
| | | .trim()); |
| | | boolean changesOnly = true; |
| | | boolean returnECs = true; |
| | | |
| | | final StringTokenizer tokenizer = new StringTokenizer(infoString, ":"); |
| | | |
| | | if (!tokenizer.hasMoreTokens()) |
| | | { |
| | | final LocalizableMessage message = ERR_PSEARCH_MISSING_DESCRIPTOR.get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | else |
| | | { |
| | | final String token = tokenizer.nextToken(); |
| | | if (!token.equals("ps")) |
| | | { |
| | | final LocalizableMessage message = ERR_PSEARCH_DOESNT_START_WITH_PS |
| | | .get(String.valueOf(infoString)); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | final ArrayList<PersistentSearchChangeType> ct = new ArrayList<PersistentSearchChangeType>( |
| | | 4); |
| | | if (tokenizer.hasMoreTokens()) |
| | | { |
| | | final StringTokenizer st = new StringTokenizer(tokenizer.nextToken(), |
| | | ", "); |
| | | if (!st.hasMoreTokens()) |
| | | { |
| | | ct.add(PersistentSearchChangeType.ADD); |
| | | ct.add(PersistentSearchChangeType.DELETE); |
| | | ct.add(PersistentSearchChangeType.MODIFY); |
| | | ct.add(PersistentSearchChangeType.MODIFY_DN); |
| | | } |
| | | else |
| | | { |
| | | do |
| | | { |
| | | final String token = st.nextToken(); |
| | | if (token.equals("add")) |
| | | { |
| | | ct.add(PersistentSearchChangeType.ADD); |
| | | } |
| | | else if (token.equals("delete") || token.equals("del")) |
| | | { |
| | | ct.add(PersistentSearchChangeType.DELETE); |
| | | } |
| | | else if (token.equals("modify") || token.equals("mod")) |
| | | { |
| | | ct.add(PersistentSearchChangeType.MODIFY); |
| | | } |
| | | else if (token.equals("modifydn") || token.equals("moddn") |
| | | || token.equals("modrdn")) |
| | | { |
| | | ct.add(PersistentSearchChangeType.MODIFY_DN); |
| | | } |
| | | else if (token.equals("any") || token.equals("all")) |
| | | { |
| | | ct.add(PersistentSearchChangeType.ADD); |
| | | ct.add(PersistentSearchChangeType.DELETE); |
| | | ct.add(PersistentSearchChangeType.MODIFY); |
| | | ct.add(PersistentSearchChangeType.MODIFY_DN); |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage message = ERR_PSEARCH_INVALID_CHANGE_TYPE |
| | | .get(String.valueOf(token)); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | while (st.hasMoreTokens()); |
| | | } |
| | | } |
| | | |
| | | if (tokenizer.hasMoreTokens()) |
| | | { |
| | | final String token = tokenizer.nextToken(); |
| | | if (token.equals("1") || token.equals("true") || token.equals("yes")) |
| | | { |
| | | changesOnly = true; |
| | | } |
| | | else if (token.equals("0") || token.equals("false") |
| | | || token.equals("no")) |
| | | { |
| | | changesOnly = false; |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage message = ERR_PSEARCH_INVALID_CHANGESONLY |
| | | .get(String.valueOf(token)); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | if (tokenizer.hasMoreTokens()) |
| | | { |
| | | final String token = tokenizer.nextToken(); |
| | | if (token.equals("1") || token.equals("true") || token.equals("yes")) |
| | | { |
| | | returnECs = true; |
| | | } |
| | | else if (token.equals("0") || token.equals("false") |
| | | || token.equals("no")) |
| | | { |
| | | returnECs = false; |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage message = ERR_PSEARCH_INVALID_RETURN_ECS |
| | | .get(String.valueOf(token)); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | final PersistentSearchRequestControl psearchControl = PersistentSearchRequestControl |
| | | .newControl(true, changesOnly, returnECs, ct |
| | | .toArray(new PersistentSearchChangeType[ct.size()])); |
| | | search.addControl(psearchControl); |
| | | } |
| | | |
| | | if (assertionFilter.isPresent()) |
| | | { |
| | | final String filterString = assertionFilter.getValue(); |
| | | Filter filter; |
| | | try |
| | | { |
| | | filter = Filter.valueOf(filterString); |
| | | |
| | | // FIXME -- Change this to the correct OID when the official one |
| | | // is assigned. |
| | | final Control assertionControl = AssertionRequestControl.newControl( |
| | | true, filter); |
| | | search.addControl(assertionControl); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException le) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_ASSERTION_INVALID_FILTER |
| | | .get(le.getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | if (matchedValuesFilter.isPresent()) |
| | | { |
| | | final LinkedList<String> mvFilterStrings = matchedValuesFilter |
| | | .getValues(); |
| | | final List<Filter> mvFilters = new ArrayList<Filter>(); |
| | | for (final String s : mvFilterStrings) |
| | | { |
| | | try |
| | | { |
| | | final Filter f = Filter.valueOf(s); |
| | | mvFilters.add(f); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException le) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_MATCHEDVALUES_INVALID_FILTER |
| | | .get(le.getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | final MatchedValuesRequestControl mvc = MatchedValuesRequestControl |
| | | .newControl(true, mvFilters); |
| | | search.addControl(mvc); |
| | | } |
| | | |
| | | if (sortOrder.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | search.addControl(ServerSideSortRequestControl.newControl(false, |
| | | sortOrder.getValue())); |
| | | } |
| | | catch (final LocalizedIllegalArgumentException le) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAP_SORTCONTROL_INVALID_ORDER |
| | | .get(le.getMessageObject()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | if (vlvDescriptor.isPresent()) |
| | | { |
| | | if (!sortOrder.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPSEARCH_VLV_REQUIRES_SORT |
| | | .get(vlvDescriptor.getLongIdentifier(), sortOrder |
| | | .getLongIdentifier()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final StringTokenizer tokenizer = new StringTokenizer(vlvDescriptor |
| | | .getValue(), ":"); |
| | | final int numTokens = tokenizer.countTokens(); |
| | | if (numTokens == 3) |
| | | { |
| | | try |
| | | { |
| | | final int beforeCount = Integer.parseInt(tokenizer.nextToken()); |
| | | final int afterCount = Integer.parseInt(tokenizer.nextToken()); |
| | | final ByteString assertionValue = ByteString.valueOf(tokenizer |
| | | .nextToken()); |
| | | search.addControl(VirtualListViewRequestControl.newAssertionControl( |
| | | true, assertionValue, beforeCount, afterCount, null)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR |
| | | .get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | else if (numTokens == 4) |
| | | { |
| | | try |
| | | { |
| | | final int beforeCount = Integer.parseInt(tokenizer.nextToken()); |
| | | final int afterCount = Integer.parseInt(tokenizer.nextToken()); |
| | | final int offset = Integer.parseInt(tokenizer.nextToken()); |
| | | final int contentCount = Integer.parseInt(tokenizer.nextToken()); |
| | | search.addControl(VirtualListViewRequestControl.newOffsetControl( |
| | | true, offset, contentCount, beforeCount, afterCount, null)); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR |
| | | .get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage message = ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR |
| | | .get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | |
| | | int pageSize = 0; |
| | | if (simplePageSize.isPresent()) |
| | | { |
| | | if (filters.size() > 1) |
| | | { |
| | | final LocalizableMessage message = ERR_PAGED_RESULTS_REQUIRES_SINGLE_FILTER |
| | | .get(); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | try |
| | | { |
| | | pageSize = simplePageSize.getIntValue(); |
| | | search.addControl(SimplePagedResultsControl.newControl(true, pageSize, |
| | | ByteString.empty())); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | } |
| | | /* |
| | | * if(connectionOptions.useSASLExternal()) { if(!connectionOptions.useSSL() |
| | | * && !connectionOptions.useStartTLS()) { LocalizableMessage message = |
| | | * ERR_TOOL_SASLEXTERNAL_NEEDS_SSL_OR_TLS.get(); |
| | | * err.println(wrapText(message, MAX_LINE_WIDTH)); return |
| | | * CLIENT_SIDE_PARAM_ERROR; } if(keyStorePathValue == null) { |
| | | * LocalizableMessage message = ERR_TOOL_SASLEXTERNAL_NEEDS_KEYSTORE.get(); |
| | | * err.println(wrapText(message, MAX_LINE_WIDTH)); return |
| | | * CLIENT_SIDE_PARAM_ERROR; } } |
| | | * connectionOptions.setVerbose(verbose.isPresent()); |
| | | */ |
| | | |
| | | int wrapColumn = 80; |
| | | if (dontWrap.isPresent()) |
| | | { |
| | | wrapColumn = 0; |
| | | } |
| | | |
| | | if (noop.isPresent()) |
| | | { |
| | | // We don't actually need to open a connection or perform the |
| | | // search, so we're done. We should return 0 to either mean that the |
| | | // processing was successful or that there were no matching entries, based |
| | | // on countEntries.isPresent() (but in either case the return value should |
| | | // be zero). |
| | | return 0; |
| | | } |
| | | |
| | | Connection connection; |
| | | try |
| | | { |
| | | connection = connectionFactory.getConnection(); |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(this, ere); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | println(LocalizableMessage.raw(e.getLocalizedMessage())); |
| | | return ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue(); |
| | | } |
| | | |
| | | Utils.printPasswordPolicyResults(this, connection); |
| | | |
| | | try |
| | | { |
| | | int filterIndex = 0; |
| | | ldifWriter = new LDIFEntryWriter(getOutputStream()) |
| | | .setWrapColumn(wrapColumn); |
| | | final LDAPSearchResultHandler resultHandler = new LDAPSearchResultHandler(); |
| | | while (true) |
| | | { |
| | | Result result; |
| | | try |
| | | { |
| | | result = connection.search(search, resultHandler); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // This shouldn't happen because there are no other threads to |
| | | // interrupt this one. |
| | | result = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setCause(e).setDiagnosticMessage(e.getLocalizedMessage()); |
| | | throw ErrorResultException.wrap(result); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final ServerSideSortResponseControl control = result.getControl( |
| | | ServerSideSortResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | if (control.getResult() != ResultCode.SUCCESS) |
| | | { |
| | | final LocalizableMessage msg = WARN_LDAPSEARCH_SORT_ERROR |
| | | .get(control.getResult().toString()); |
| | | println(msg); |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final VirtualListViewResponseControl control = result.getControl( |
| | | VirtualListViewResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | if (control.getResult() == ResultCode.SUCCESS) |
| | | { |
| | | LocalizableMessage msg = INFO_LDAPSEARCH_VLV_TARGET_OFFSET |
| | | .get(control.getTargetPosition()); |
| | | println(msg); |
| | | |
| | | msg = INFO_LDAPSEARCH_VLV_CONTENT_COUNT.get(control |
| | | .getContentCount()); |
| | | println(msg); |
| | | } |
| | | else |
| | | { |
| | | final LocalizableMessage msg = WARN_LDAPSEARCH_VLV_ERROR |
| | | .get(control.getResult().toString()); |
| | | println(msg); |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | SimplePagedResultsControl control = result.getControl( |
| | | SimplePagedResultsControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | if (control.getCookie().length() > 0) |
| | | { |
| | | if (!isQuiet()) |
| | | { |
| | | pressReturnToContinue(); |
| | | } |
| | | final Iterator<Control> iterator = search.getControls() |
| | | .iterator(); |
| | | while (iterator.hasNext()) |
| | | { |
| | | if (iterator.next().getOID().equals( |
| | | SimplePagedResultsControl.OID)) |
| | | { |
| | | iterator.remove(); |
| | | } |
| | | } |
| | | control = SimplePagedResultsControl.newControl(true, pageSize, |
| | | control.getCookie()); |
| | | search.addControl(control); |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | println(); |
| | | println(ERR_TOOL_RESULT_CODE.get(result.getResultCode().intValue(), |
| | | result.getResultCode().toString())); |
| | | if ((result.getDiagnosticMessage() != null) |
| | | && (result.getDiagnosticMessage().length() > 0)) |
| | | { |
| | | println(LocalizableMessage.raw(result.getDiagnosticMessage())); |
| | | } |
| | | if (result.getMatchedDN() != null && result.getMatchedDN().length() > 0) |
| | | { |
| | | println(ERR_TOOL_MATCHED_DN.get(result.getMatchedDN())); |
| | | } |
| | | |
| | | filterIndex++; |
| | | if (filterIndex < filters.size()) |
| | | { |
| | | search.setFilter(filters.get(filterIndex)); |
| | | } |
| | | else |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (countEntries.isPresent() && !isQuiet()) |
| | | { |
| | | final LocalizableMessage message = INFO_LDAPSEARCH_MATCHING_ENTRY_COUNT |
| | | .get(resultHandler.entryCount); |
| | | println(message); |
| | | println(); |
| | | } |
| | | } |
| | | catch (final ErrorResultException ere) |
| | | { |
| | | return Utils.printErrorMessage(this, ere); |
| | | } |
| | | finally |
| | | { |
| | | connection.close(); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | |
| | | import org.glassfish.grizzly.TransportFactory; |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.ModifyRequest; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.responses.Result; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A load generation tool that can be used to load a Directory Server with |
| | | * Modify requests using one or more LDAP connections. |
| | | */ |
| | | public final class ModRate extends ConsoleApplication |
| | | { |
| | | private static final class ModifyPerformanceRunner extends PerformanceRunner |
| | | { |
| | | private final class ModifyWorkerThread extends ConnectionWorker |
| | | { |
| | | private ModifyRequest mr; |
| | | private Object[] data; |
| | | |
| | | |
| | | |
| | | private ModifyWorkerThread(final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | super(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public FutureResult<?> performOperation( |
| | | final AsynchronousConnection connection, |
| | | final DataSource[] dataSources, final long startTime) |
| | | { |
| | | if (dataSources != null) |
| | | { |
| | | data = DataSource.generateData(dataSources, data); |
| | | } |
| | | mr = newModifyRequest(data); |
| | | return connection.modify(mr, new UpdateStatsResultHandler<Result>( |
| | | startTime, connection, this)); |
| | | } |
| | | |
| | | |
| | | |
| | | private ModifyRequest newModifyRequest(final Object[] data) |
| | | { |
| | | String formattedString; |
| | | int colonPos; |
| | | ModifyRequest mr; |
| | | if (data == null) |
| | | { |
| | | mr = Requests.newModifyRequest(baseDN); |
| | | } |
| | | else |
| | | { |
| | | mr = Requests.newModifyRequest(String.format(baseDN, data)); |
| | | } |
| | | for (final String modString : modStrings) |
| | | { |
| | | if (data == null) |
| | | { |
| | | formattedString = modString; |
| | | } |
| | | else |
| | | { |
| | | formattedString = String.format(modString, data); |
| | | } |
| | | colonPos = formattedString.indexOf(':'); |
| | | if (colonPos > 0) |
| | | { |
| | | mr.addModification(ModificationType.REPLACE, |
| | | formattedString.substring(0, colonPos), |
| | | formattedString.substring(colonPos + 1)); |
| | | } |
| | | } |
| | | return mr; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private String baseDN; |
| | | |
| | | private String[] modStrings; |
| | | |
| | | |
| | | |
| | | private ModifyPerformanceRunner(final ArgumentParser argParser, |
| | | final ConsoleApplication app) throws ArgumentException |
| | | { |
| | | super(argParser, app, false, false, false); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | ConnectionWorker newConnectionWorker( |
| | | final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | return new ModifyWorkerThread(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | StatsThread newStatsThread() |
| | | { |
| | | return new StatsThread(new String[0]); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The main method for ModRate tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainModRate(args, System.in, System.out, System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the modrate tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainModRate(final String[] args) |
| | | { |
| | | return mainModRate(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the modrate tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainModRate(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | |
| | | { |
| | | return new ModRate(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | private BooleanArgument scriptFriendly; |
| | | |
| | | |
| | | |
| | | private ModRate(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return scriptFriendly.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_MODRATE_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser( |
| | | ModRate.class.getName(), toolDescription, false, true, 1, 0, |
| | | "[(attribute:value format string) ...]"); |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | ModifyPerformanceRunner runner; |
| | | |
| | | BooleanArgument showUsage; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | StringArgument baseDN; |
| | | |
| | | try |
| | | { |
| | | TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory()); |
| | | connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this); |
| | | runner = new ModifyPerformanceRunner(argParser, this); |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | baseDN = new StringArgument("targetDN", OPTION_SHORT_BASEDN, |
| | | OPTION_LONG_TARGETDN, true, false, true, |
| | | INFO_TARGETDN_PLACEHOLDER.get(), null, null, |
| | | INFO_MODRATE_TOOL_DESCRIPTION_TARGETDN.get()); |
| | | baseDN.setPropertyName(OPTION_LONG_BASEDN); |
| | | argParser.addArgument(baseDN); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | |
| | | scriptFriendly = new BooleanArgument("scriptFriendly", 'S', |
| | | "scriptFriendly", INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()); |
| | | scriptFriendly.setPropertyName("scriptFriendly"); |
| | | argParser.addArgument(scriptFriendly); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = connectionFactoryProvider |
| | | .getAuthenticatedConnectionFactory(); |
| | | runner.validate(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | runner.modStrings = argParser.getTrailingArguments().toArray( |
| | | new String[argParser.getTrailingArguments().size()]); |
| | | runner.baseDN = baseDN.getValue(); |
| | | |
| | | try |
| | | { |
| | | |
| | | // Try it out to make sure the format string and data sources |
| | | // match. |
| | | final Object[] data = DataSource.generateData(runner.getDataSources(), |
| | | null); |
| | | for (final String modString : runner.modStrings) |
| | | { |
| | | String.format(modString, data); |
| | | } |
| | | String.format(runner.baseDN, data); |
| | | } |
| | | catch (final Exception ex1) |
| | | { |
| | | println(LocalizableMessage.raw("Error formatting filter or base DN: " |
| | | + ex1.toString())); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | return runner.run(connectionFactory); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_MCARG_VALUE_NOT_ALLOWED; |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an argument type that will only accept one or more of a |
| | | * specific set of string values. |
| | | * |
| | | * @param <T> |
| | | * The type of values returned by this argument. |
| | | */ |
| | | final class MultiChoiceArgument<T> extends Argument |
| | | { |
| | | // Indicates whether argument values should be treated in a |
| | | // case-sensitive manner. |
| | | private final boolean caseSensitive; |
| | | |
| | | // The set of values that will be allowed for use with this argument. |
| | | private final Collection<T> allowedValues; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new string argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param allowedValues |
| | | * The set of values that are allowed for use for this argument. If |
| | | * they are not to be treated in a case-sensitive value then they |
| | | * should all be formatted in lowercase. |
| | | * @param caseSensitive |
| | | * Indicates whether the set of allowed values should be treated in a |
| | | * case-sensitive manner. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public MultiChoiceArgument(final String name, |
| | | final Character shortIdentifier, final String longIdentifier, |
| | | final boolean isRequired, final boolean isMultiValued, |
| | | final boolean needsValue, final LocalizableMessage valuePlaceholder, |
| | | final String defaultValue, final String propertyName, |
| | | final Collection<T> allowedValues, final boolean caseSensitive, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, defaultValue, propertyName, description); |
| | | |
| | | this.allowedValues = allowedValues; |
| | | this.caseSensitive = caseSensitive; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new string argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param allowedValues |
| | | * The set of values that are allowed for use for this argument. If |
| | | * they are not to be treated in a case-sensitive value then they |
| | | * should all be formatted in lowercase. |
| | | * @param caseSensitive |
| | | * Indicates whether the set of allowed values should be treated in a |
| | | * case-sensitive manner. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public MultiChoiceArgument(final String name, |
| | | final Character shortIdentifier, final String longIdentifier, |
| | | final boolean isRequired, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, |
| | | final Collection<T> allowedValues, final boolean caseSensitive, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, |
| | | valuePlaceholder, null, null, description); |
| | | |
| | | this.allowedValues = allowedValues; |
| | | this.caseSensitive = caseSensitive; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of allowed values for this argument. The contents of this |
| | | * set must not be altered by the caller. |
| | | * |
| | | * @return The set of allowed values for this argument. |
| | | */ |
| | | public Collection<T> getAllowedValues() |
| | | { |
| | | return allowedValues; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the string vale for this argument. If it has multiple values, |
| | | * then the first will be returned. If it does not have any values, then the |
| | | * default value will be returned. |
| | | * |
| | | * @return The string value for this argument, or <CODE>null</CODE> if there |
| | | * are no values and no default value has been given. |
| | | * @throws ArgumentException |
| | | * The value cannot be parsed. |
| | | */ |
| | | public T getTypedValue() throws ArgumentException |
| | | { |
| | | final String v = super.getValue(); |
| | | if (v == null) |
| | | { |
| | | return null; |
| | | } |
| | | for (final T o : allowedValues) |
| | | { |
| | | if ((caseSensitive && o.toString().equals(v)) |
| | | || o.toString().equalsIgnoreCase(v)) |
| | | { |
| | | return o; |
| | | } |
| | | } |
| | | // TODO: Some message |
| | | throw new ArgumentException(null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the set of allowed values for this argument should be |
| | | * treated in a case-sensitive manner. |
| | | * |
| | | * @return <CODE>true</CODE> if the values are to be treated in a |
| | | * case-sensitive manner, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isCaseSensitive() |
| | | { |
| | | return caseSensitive; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies the default value that will be used for this argument if it is |
| | | * not specified on the command line and it is not set from a properties file. |
| | | * |
| | | * @param defaultValue |
| | | * The default value that will be used for this argument if it is not |
| | | * specified on the command line and it is not set from a properties |
| | | * file. |
| | | */ |
| | | public void setDefaultValue(final T defaultValue) |
| | | { |
| | | super.setDefaultValue(defaultValue.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | @Override |
| | | public boolean valueIsAcceptable(final String valueString, |
| | | final LocalizableMessageBuilder invalidReason) |
| | | { |
| | | for (final T o : allowedValues) |
| | | { |
| | | if ((caseSensitive && o.toString().equals(valueString)) |
| | | || o.toString().equalsIgnoreCase(valueString)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED |
| | | .get(getName(), valueString)); |
| | | |
| | | return false; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import java.util.Enumeration; |
| | | import java.util.Vector; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Utility class for printing aligned columns of text. |
| | | * <P> |
| | | * This class allows you to specify: |
| | | * <UL> |
| | | * <LI>The number of columns in the output. This will determine the dimension of |
| | | * the string arrays passed to add(String[]) or addTitle(String[]). |
| | | * <LI>spacing/gap between columns |
| | | * <LI>character to use for title border (null means no border) |
| | | * <LI>column alignment. Only LEFT/CENTER is supported for now. |
| | | * </UL> |
| | | * <P> |
| | | * Example usage: |
| | | * |
| | | * <PRE> |
| | | * MyPrinter mp = new MyPrinter(3, 2, "-"); |
| | | * String oneRow[] = new String[3]; |
| | | * oneRow[0] = "User Name"; |
| | | * oneRow[1] = "Email Address"; |
| | | * oneRow[2] = "Phone Number"; |
| | | * mp.addTitle(oneRow); |
| | | * oneRow[0] = "Bob"; |
| | | * oneRow[1] = "bob@foo.com"; |
| | | * oneRow[2] = "123-4567"; |
| | | * mp.add(oneRow); |
| | | * oneRow[0] = "John"; |
| | | * oneRow[1] = "john@foo.com"; |
| | | * oneRow[2] = "456-7890"; |
| | | * mp.add(oneRow); |
| | | * mp.print(); |
| | | * </PRE> |
| | | * <P> |
| | | * The above would print: |
| | | * <P> |
| | | * |
| | | * <PRE> |
| | | * -------------------------------------- |
| | | * User Name Email Address Phone Number |
| | | * -------------------------------------- |
| | | * Bob bob@foo.com 123-4567 |
| | | * John john@foo.com 456-7890 |
| | | * </PRE> |
| | | * <P> |
| | | * This class also supports multi-row titles and having title strings spanning |
| | | * multiple collumns. Example usage: |
| | | * |
| | | * <PRE> |
| | | * TestPrinter tp = new TestPrinter(4, 2, "-"); |
| | | * String oneRow[] = new String[4]; |
| | | * int[] span = new int[4]; |
| | | * span[0] = 2; // spans 2 collumns |
| | | * span[1] = 0; // spans 0 collumns |
| | | * span[2] = 2; // spans 2 collumns |
| | | * span[3] = 0; // spans 0 collumns |
| | | * tp.setTitleAlign(CENTER); |
| | | * oneRow[0] = "Name"; |
| | | * oneRow[1] = ""; |
| | | * oneRow[2] = "Contact"; |
| | | * oneRow[3] = ""; |
| | | * tp.addTitle(oneRow, span); |
| | | * oneRow[0] = "First"; |
| | | * oneRow[1] = "Last"; |
| | | * oneRow[2] = "Email"; |
| | | * oneRow[3] = "Phone"; |
| | | * tp.addTitle(oneRow); |
| | | * oneRow[0] = "Bob"; |
| | | * oneRow[1] = "Jones"; |
| | | * oneRow[2] = "bob@foo.com"; |
| | | * oneRow[3] = "123-4567"; |
| | | * tp.add(oneRow); |
| | | * oneRow[0] = "John"; |
| | | * oneRow[1] = "Doe"; |
| | | * oneRow[2] = "john@foo.com"; |
| | | * oneRow[3] = "456-7890"; |
| | | * tp.add(oneRow); |
| | | * tp.println(); |
| | | * </PRE> |
| | | * <P> |
| | | * The above would print: |
| | | * <P> |
| | | * |
| | | * <PRE> |
| | | * ------------------------------------ |
| | | * Name Contact |
| | | * First Last Email Phone |
| | | * ------------------------------------ |
| | | * Bob Jones bob@foo.com 123-4567 |
| | | * John Doe john@foo.com 456-7890 |
| | | * </PRE> |
| | | */ |
| | | final class MultiColumnPrinter |
| | | { |
| | | |
| | | final public static int LEFT = 0; |
| | | |
| | | final public static int CENTER = 1; |
| | | |
| | | final public static int RIGHT = 2; |
| | | |
| | | private int numCol = 2; |
| | | |
| | | private int gap = 4; |
| | | |
| | | private int align = CENTER; |
| | | |
| | | private int titleAlign = CENTER; |
| | | |
| | | private String border = null; |
| | | |
| | | private Vector<String[]> titleTable = null; |
| | | |
| | | private Vector<int[]> titleSpanTable = null; |
| | | |
| | | private final int curLength[]; |
| | | |
| | | private final ConsoleApplication app; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a sorted new MultiColumnPrinter class using LEFT alignment and with |
| | | * no title border. |
| | | * |
| | | * @param numCol |
| | | * number of columns |
| | | * @param gap |
| | | * gap between each column |
| | | */ |
| | | MultiColumnPrinter(final int numCol, final int gap, |
| | | final ConsoleApplication app) |
| | | { |
| | | this(numCol, gap, null, LEFT, app); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a sorted new MultiColumnPrinter class using LEFT alignment. |
| | | * |
| | | * @param numCol |
| | | * number of columns |
| | | * @param gap |
| | | * gap between each column |
| | | * @param border |
| | | * character used to frame the titles |
| | | */ |
| | | MultiColumnPrinter(final int numCol, final int gap, final String border, |
| | | final ConsoleApplication app) |
| | | { |
| | | this(numCol, gap, border, LEFT, app); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new MultiColumnPrinter class. |
| | | * |
| | | * @param numCol |
| | | * number of columns |
| | | * @param gap |
| | | * gap between each column |
| | | * @param border |
| | | * character used to frame the titles |
| | | * @param align |
| | | * type of alignment within columns |
| | | */ |
| | | MultiColumnPrinter(final int numCol, final int gap, final String border, |
| | | final int align, final ConsoleApplication app) |
| | | { |
| | | |
| | | titleTable = new Vector<String[]>(); |
| | | titleSpanTable = new Vector<int[]>(); |
| | | curLength = new int[numCol]; |
| | | |
| | | this.numCol = numCol; |
| | | this.gap = gap; |
| | | this.border = border; |
| | | this.align = align; |
| | | this.titleAlign = LEFT; |
| | | |
| | | this.app = app; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds to the row of strings to be used as the title for the table. |
| | | * |
| | | * @param row |
| | | * Array of strings to print in one row of title. |
| | | */ |
| | | void addTitle(final String[] row) |
| | | { |
| | | if (row == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | final int[] span = new int[row.length]; |
| | | for (int i = 0; i < row.length; i++) |
| | | { |
| | | span[i] = 1; |
| | | } |
| | | |
| | | addTitle(row, span); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds to the row of strings to be used as the title for the table. Also |
| | | * allows for certain title strings to span multiple collumns The span |
| | | * parameter is an array of integers which indicate how many collumns the |
| | | * corresponding title string will occupy. For a row that is 4 collumns wide, |
| | | * it is possible to have some title strings in a row to 'span' multiple |
| | | * collumns: |
| | | * <P> |
| | | * |
| | | * <PRE> |
| | | * ------------------------------------ |
| | | * Name Contact |
| | | * First Last Email Phone |
| | | * ------------------------------------ |
| | | * Bob Jones bob@foo.com 123-4567 |
| | | * John Doe john@foo.com 456-7890 |
| | | * </PRE> |
| | | * |
| | | * In the example above, the title row has a string 'Name' that spans 2 |
| | | * collumns. The string 'Contact' also spans 2 collumns. The above is done by |
| | | * passing in to addTitle() an array that contains: |
| | | * |
| | | * <PRE> |
| | | * span[0] = 2; // spans 2 collumns |
| | | * span[1] = 0; // spans 0 collumns, ignore |
| | | * span[2] = 2; // spans 2 collumns |
| | | * span[3] = 0; // spans 0 collumns, ignore |
| | | * </PRE> |
| | | * <P> |
| | | * A span value of 1 is the default. The method addTitle(String[] row) |
| | | * basically does: |
| | | * |
| | | * <PRE> |
| | | * int[] span = new int[row.length]; |
| | | * for (int i = 0; i < row.length; i++) |
| | | * { |
| | | * span[i] = 1; |
| | | * } |
| | | * addTitle(row, span); |
| | | * </PRE> |
| | | * |
| | | * @param row |
| | | * Array of strings to print in one row of title. |
| | | * @param span |
| | | * Array of integers that reflect the number of collumns the |
| | | * corresponding title string will occupy. |
| | | */ |
| | | void addTitle(final String[] row, final int span[]) |
| | | { |
| | | // Need to create a new instance of it, otherwise the new values |
| | | // will always overwrite the old values. |
| | | |
| | | final String[] rowInstance = new String[(row.length)]; |
| | | for (int i = 0; i < row.length; i++) |
| | | { |
| | | rowInstance[i] = row[i]; |
| | | } |
| | | titleTable.addElement(rowInstance); |
| | | |
| | | titleSpanTable.addElement(span); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears title strings. |
| | | */ |
| | | void clearTitle() |
| | | { |
| | | titleTable.clear(); |
| | | titleSpanTable.clear(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds one row of text to output. |
| | | * |
| | | * @param row |
| | | * Array of strings to print in one row. |
| | | */ |
| | | void printRow(final String... row) |
| | | { |
| | | for (int i = 0; i < numCol; i++) |
| | | { |
| | | if (titleAlign == RIGHT) |
| | | { |
| | | final int spaceBefore = curLength[i] - row[i].length(); |
| | | printSpaces(spaceBefore); |
| | | app.getOutputStream().print(row[i]); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(gap); |
| | | } |
| | | } |
| | | else if (align == CENTER) |
| | | { |
| | | int space1, space2; |
| | | space1 = (curLength[i] - row[i].length()) / 2; |
| | | space2 = curLength[i] - row[i].length() - space1; |
| | | |
| | | printSpaces(space1); |
| | | app.getOutputStream().print(row[i]); |
| | | printSpaces(space2); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(gap); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | app.getOutputStream().print(row[i]); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(curLength[i] - row[i].length() + gap); |
| | | } |
| | | } |
| | | } |
| | | app.getOutputStream().println(""); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Prints the table title |
| | | */ |
| | | void printTitle() |
| | | { |
| | | // Get the longest string for each column and store in curLength[] |
| | | |
| | | // Scan through title rows |
| | | Enumeration<String[]> elm = titleTable.elements(); |
| | | Enumeration<int[]> spanEnum = titleSpanTable.elements(); |
| | | while (elm.hasMoreElements()) |
| | | { |
| | | final String[] row = elm.nextElement(); |
| | | final int[] curSpan = spanEnum.nextElement(); |
| | | |
| | | for (int i = 0; i < numCol; i++) |
| | | { |
| | | // None of the fields should be null, but if it |
| | | // happens to be so, replace it with "-". |
| | | if (row[i] == null) |
| | | { |
| | | row[i] = "-"; |
| | | } |
| | | |
| | | int len = row[i].length(); |
| | | |
| | | /* |
| | | * If a title string spans multiple collumns, then the space it occupies |
| | | * in each collumn is at most len/span (since we have gap to take into |
| | | * account as well). |
| | | */ |
| | | final int span = curSpan[i]; |
| | | int rem = 0; |
| | | if (span > 1) |
| | | { |
| | | rem = len % span; |
| | | len = len / span; |
| | | } |
| | | |
| | | if (curLength[i] < len) |
| | | { |
| | | curLength[i] = len; |
| | | |
| | | if ((span > 1) && ((i + span) <= numCol)) |
| | | { |
| | | for (int j = i + 1; j < (i + span); ++j) |
| | | { |
| | | curLength[j] = len; |
| | | } |
| | | |
| | | /* |
| | | * Add remainder to last collumn in span to avoid round-off errors. |
| | | */ |
| | | curLength[(i + span) - 1] += rem; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | printBorder(); |
| | | elm = titleTable.elements(); |
| | | spanEnum = titleSpanTable.elements(); |
| | | |
| | | while (elm.hasMoreElements()) |
| | | { |
| | | final String[] row = elm.nextElement(); |
| | | final int[] curSpan = spanEnum.nextElement(); |
| | | |
| | | for (int i = 0; i < numCol; i++) |
| | | { |
| | | int availableSpace = 0; |
| | | final int span = curSpan[i]; |
| | | |
| | | if (span == 0) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | availableSpace = curLength[i]; |
| | | |
| | | if ((span > 1) && ((i + span) <= numCol)) |
| | | { |
| | | for (int j = i + 1; j < (i + span); ++j) |
| | | { |
| | | availableSpace += gap; |
| | | availableSpace += curLength[j]; |
| | | } |
| | | } |
| | | |
| | | if (titleAlign == RIGHT) |
| | | { |
| | | final int spaceBefore = availableSpace - row[i].length(); |
| | | printSpaces(spaceBefore); |
| | | app.getOutputStream().print(row[i]); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(gap); |
| | | } |
| | | } |
| | | else if (titleAlign == CENTER) |
| | | { |
| | | int spaceBefore, spaceAfter; |
| | | spaceBefore = (availableSpace - row[i].length()) / 2; |
| | | spaceAfter = availableSpace - row[i].length() - spaceBefore; |
| | | |
| | | printSpaces(spaceBefore); |
| | | app.getOutputStream().print(row[i]); |
| | | printSpaces(spaceAfter); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(gap); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | app.getOutputStream().print(row[i]); |
| | | if (i < numCol - 1) |
| | | { |
| | | printSpaces(availableSpace - row[i].length() + gap); |
| | | } |
| | | } |
| | | |
| | | } |
| | | app.getOutputStream().println(""); |
| | | } |
| | | printBorder(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Set alignment for title strings |
| | | * |
| | | * @param titleAlign |
| | | */ |
| | | void setTitleAlign(final int titleAlign) |
| | | { |
| | | this.titleAlign = titleAlign; |
| | | } |
| | | |
| | | |
| | | |
| | | private void printBorder() |
| | | { |
| | | if (border == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // For the value in each column |
| | | for (int i = 0; i < numCol; i++) |
| | | { |
| | | for (int j = 0; j < curLength[i]; j++) |
| | | { |
| | | app.getOutputStream().print(border); |
| | | } |
| | | } |
| | | |
| | | // For the gap between each column |
| | | for (int i = 0; i < numCol - 1; i++) |
| | | { |
| | | for (int j = 0; j < gap; j++) |
| | | { |
| | | app.getOutputStream().print(border); |
| | | } |
| | | } |
| | | app.getOutputStream().println(""); |
| | | } |
| | | |
| | | |
| | | |
| | | private void printSpaces(final int count) |
| | | { |
| | | for (int i = 0; i < count; ++i) |
| | | { |
| | | app.getOutputStream().print(" "); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.glassfish.grizzly.Grizzly; |
| | | import org.glassfish.grizzly.memory.HeapMemoryManager; |
| | | import org.glassfish.grizzly.nio.DefaultNIOTransportFactory; |
| | | import org.glassfish.grizzly.nio.DefaultSelectionKeyHandler; |
| | | import org.glassfish.grizzly.nio.DefaultSelectorHandler; |
| | | import org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorPool; |
| | | import org.glassfish.grizzly.nio.transport.TCPNIOTransport; |
| | | import org.glassfish.grizzly.nio.transport.UDPNIOTransport; |
| | | import org.glassfish.grizzly.threadpool.AbstractThreadPool; |
| | | import org.glassfish.grizzly.threadpool.GrizzlyExecutorService; |
| | | import org.glassfish.grizzly.threadpool.ThreadPoolConfig; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The TCPNIOTransportFactory which performance tools will use. |
| | | */ |
| | | public final class PerfToolTCPNIOTransportFactory extends |
| | | DefaultNIOTransportFactory |
| | | { |
| | | private int selectors; |
| | | |
| | | private int linger = 0; |
| | | |
| | | private boolean tcpNoDelay = true; |
| | | |
| | | private boolean reuseAddress = true; |
| | | |
| | | private TCPNIOTransport singletonTransport = null; |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public synchronized TCPNIOTransport createTCPTransport() |
| | | { |
| | | if (singletonTransport == null) |
| | | { |
| | | singletonTransport = super.createTCPTransport(); |
| | | |
| | | singletonTransport.setSelectorRunnersCount(selectors); |
| | | singletonTransport.setLinger(linger); |
| | | singletonTransport.setTcpNoDelay(tcpNoDelay); |
| | | singletonTransport.setReuseAddress(reuseAddress); |
| | | } |
| | | |
| | | return singletonTransport; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creating an UDP transport is unsupported with this factory. A |
| | | * {@code UnsupportedOperationException} will be thrown when this method is |
| | | * called. |
| | | * |
| | | * @return This method will always throw {@code UnsupportedOperationException} |
| | | * . |
| | | */ |
| | | @Override |
| | | public UDPNIOTransport createUDPTransport() |
| | | { |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void initialize() |
| | | { |
| | | final int cpus = Runtime.getRuntime().availableProcessors(); |
| | | int threads = Math.max(5, (cpus / 2) - 1); |
| | | selectors = Math.max(2, cpus / 8); |
| | | |
| | | final String threadsStr = System |
| | | .getProperty("org.opends.sdk.ldap.transport.threads"); |
| | | if (threadsStr != null) |
| | | { |
| | | threads = Integer.parseInt(threadsStr); |
| | | } |
| | | final String selectorsStr = System |
| | | .getProperty("org.opends.sdk.ldap.transport.selectors"); |
| | | if (selectorsStr != null) |
| | | { |
| | | selectors = Integer.parseInt(selectorsStr); |
| | | } |
| | | |
| | | final String lingerStr = System |
| | | .getProperty("org.opends.sdk.ldap.transport.linger"); |
| | | if (lingerStr != null) |
| | | { |
| | | linger = Integer.parseInt(lingerStr); |
| | | } |
| | | |
| | | final String tcpNoDelayStr = System |
| | | .getProperty("org.opends.sdk.ldap.transport.tcpNoDelay"); |
| | | if (tcpNoDelayStr != null) |
| | | { |
| | | tcpNoDelay = Integer.parseInt(tcpNoDelayStr) != 0; |
| | | } |
| | | |
| | | final String reuseAddressStr = System |
| | | .getProperty("org.opends.sdk.ldap.transport.reuseAddress"); |
| | | if (reuseAddressStr != null) |
| | | { |
| | | reuseAddress = Integer.parseInt(reuseAddressStr) != 0; |
| | | } |
| | | |
| | | // Copied from TransportFactory. |
| | | defaultAttributeBuilder = Grizzly.DEFAULT_ATTRIBUTE_BUILDER; |
| | | defaultMemoryManager = new HeapMemoryManager(); |
| | | defaultWorkerThreadPool = GrizzlyExecutorService |
| | | .createInstance(ThreadPoolConfig.defaultConfig() |
| | | .setMemoryManager(defaultMemoryManager).setCorePoolSize(threads) |
| | | .setMaxPoolSize(threads).setPoolName("OpenDS SDK Worker(Grizzly)")); |
| | | |
| | | // Copied from NIOTransportFactory. |
| | | defaultSelectorHandler = new DefaultSelectorHandler(); |
| | | defaultSelectionKeyHandler = new DefaultSelectionKeyHandler(); |
| | | |
| | | /* |
| | | * By default TemporarySelector pool size should be equal to the number of |
| | | * processing threads |
| | | */ |
| | | int selectorPoolSize = TemporarySelectorPool.DEFAULT_SELECTORS_COUNT; |
| | | if (defaultWorkerThreadPool instanceof AbstractThreadPool) |
| | | { |
| | | selectorPoolSize = Math.min( |
| | | ((AbstractThreadPool) defaultWorkerThreadPool).getConfig() |
| | | .getMaxPoolSize(), selectorPoolSize); |
| | | } |
| | | defaultTemporarySelectorPool = new TemporarySelectorPool(selectorPoolSize); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import java.io.IOException; |
| | | import java.lang.management.GarbageCollectorMXBean; |
| | | import java.lang.management.ManagementFactory; |
| | | import java.util.*; |
| | | import java.util.concurrent.CountDownLatch; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.concurrent.atomic.AtomicLong; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.responses.BindResult; |
| | | import org.opends.sdk.responses.ExtendedResult; |
| | | import org.opends.sdk.responses.Result; |
| | | |
| | | import com.sun.opends.sdk.tools.AuthenticatedConnectionFactory.AuthenticatedAsynchronousConnection; |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Benchmark application framework. |
| | | */ |
| | | abstract class PerformanceRunner implements ConnectionEventListener |
| | | { |
| | | abstract class ConnectionWorker |
| | | { |
| | | private final AtomicInteger operationsInFlight = new AtomicInteger(); |
| | | |
| | | private volatile int count; |
| | | |
| | | private final AsynchronousConnection staticConnection; |
| | | |
| | | private final ConnectionFactory connectionFactory; |
| | | |
| | | private final CountDownLatch latch = new CountDownLatch(1); |
| | | |
| | | |
| | | |
| | | ConnectionWorker(final AsynchronousConnection staticConnection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | this.staticConnection = staticConnection; |
| | | this.connectionFactory = connectionFactory; |
| | | } |
| | | |
| | | |
| | | |
| | | public void operationCompleted(final AsynchronousConnection connection) |
| | | { |
| | | if (operationsInFlight.decrementAndGet() == 0 |
| | | && this.staticConnection == null) |
| | | { |
| | | connection.close(); |
| | | } |
| | | startWork(); |
| | | } |
| | | |
| | | |
| | | |
| | | public abstract FutureResult<?> performOperation( |
| | | final AsynchronousConnection connection, |
| | | final DataSource[] dataSources, final long startTime); |
| | | |
| | | |
| | | |
| | | public void startWork() |
| | | { |
| | | if (!stopRequested && !(maxIterations > 0 && count >= maxIterations)) |
| | | { |
| | | if (this.staticConnection == null) |
| | | { |
| | | connectionFactory |
| | | .getAsynchronousConnection(new ResultHandler<AsynchronousConnection>() |
| | | { |
| | | public void handleErrorResult(final ErrorResultException e) |
| | | { |
| | | app.println(LocalizableMessage.raw(e.getResult() |
| | | .getDiagnosticMessage())); |
| | | if (e.getCause() != null && app.isVerbose()) |
| | | { |
| | | e.getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | stopRequested = true; |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleResult(final AsynchronousConnection result) |
| | | { |
| | | doWork(result); |
| | | } |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | if (!noRebind |
| | | && this.staticConnection instanceof AuthenticatedAsynchronousConnection) |
| | | { |
| | | final AuthenticatedAsynchronousConnection ac = |
| | | (AuthenticatedAsynchronousConnection) this.staticConnection; |
| | | ac.rebind(new ResultHandler<BindResult>() |
| | | { |
| | | public void handleErrorResult(final ErrorResultException e) |
| | | { |
| | | app.println(LocalizableMessage.raw(e.getResult().toString())); |
| | | if (e.getCause() != null && app.isVerbose()) |
| | | { |
| | | e.getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | stopRequested = true; |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleResult(final BindResult result) |
| | | { |
| | | doWork(staticConnection); |
| | | } |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | doWork(staticConnection); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | latch.countDown(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void waitFor() throws InterruptedException |
| | | { |
| | | latch.await(); |
| | | } |
| | | |
| | | |
| | | |
| | | private void doWork(final AsynchronousConnection connection) |
| | | { |
| | | long start; |
| | | double sleepTimeInMS = 0; |
| | | final int opsToPerform = isAsync ? numConcurrentTasks : numConcurrentTasks |
| | | - operationsInFlight.get(); |
| | | for (int i = 0; i < opsToPerform; i++) |
| | | { |
| | | if (maxIterations > 0 && count >= maxIterations) |
| | | { |
| | | break; |
| | | } |
| | | start = System.nanoTime(); |
| | | performOperation(connection, dataSources.get(), start); |
| | | operationRecentCount.getAndIncrement(); |
| | | operationsInFlight.getAndIncrement(); |
| | | count++; |
| | | |
| | | if (targetThroughput > 0) |
| | | { |
| | | try |
| | | { |
| | | if (sleepTimeInMS > 1) |
| | | { |
| | | Thread.sleep((long) Math.floor(sleepTimeInMS)); |
| | | } |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | sleepTimeInMS += targetTimeInMS |
| | | - ((System.nanoTime() - start) / 1000000.0); |
| | | if (sleepTimeInMS < -60000) |
| | | { |
| | | // If we fall behind by 60 seconds, just forget about |
| | | // catching up |
| | | sleepTimeInMS = -60000; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Statistics thread base implementation. |
| | | */ |
| | | class StatsThread extends Thread |
| | | { |
| | | private final String[] additionalColumns; |
| | | |
| | | private final List<GarbageCollectorMXBean> beans; |
| | | |
| | | private final Set<Double> percentiles; |
| | | |
| | | private final int numColumns; |
| | | |
| | | private ReversableArray etimes = new ReversableArray(100000); |
| | | |
| | | private final ReversableArray array = new ReversableArray(200000); |
| | | |
| | | protected long totalSuccessCount; |
| | | |
| | | protected long totalOperationCount; |
| | | |
| | | protected long totalFailedCount; |
| | | |
| | | protected long totalWaitTime; |
| | | |
| | | protected int successCount; |
| | | |
| | | protected int operationCount; |
| | | |
| | | protected int failedCount; |
| | | |
| | | protected long waitTime; |
| | | |
| | | protected long lastStatTime; |
| | | |
| | | protected long lastGCDuration; |
| | | |
| | | protected double recentDuration; |
| | | |
| | | protected double averageDuration; |
| | | |
| | | |
| | | |
| | | public StatsThread(final String[] additionalColumns) |
| | | { |
| | | super("Stats Thread"); |
| | | |
| | | this.additionalColumns = additionalColumns; |
| | | |
| | | final TreeSet<Double> pSet = new TreeSet<Double>(); |
| | | if (!percentilesArgument.isPresent()) |
| | | { |
| | | pSet.add(.1); |
| | | pSet.add(.01); |
| | | pSet.add(.001); |
| | | } |
| | | else |
| | | { |
| | | for (final String percentile : percentilesArgument.getValues()) |
| | | { |
| | | pSet.add(100.0 - Double.parseDouble(percentile)); |
| | | } |
| | | } |
| | | this.percentiles = pSet.descendingSet(); |
| | | this.numColumns = 5 + this.percentiles.size() + additionalColumns.length |
| | | + (isAsync ? 1 : 0); |
| | | this.beans = ManagementFactory.getGarbageCollectorMXBeans(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void run() |
| | | { |
| | | final MultiColumnPrinter printer; |
| | | |
| | | if (!app.isScriptFriendly()) |
| | | { |
| | | printer = new MultiColumnPrinter(numColumns, 2, "-", |
| | | MultiColumnPrinter.RIGHT, app); |
| | | printer.setTitleAlign(MultiColumnPrinter.RIGHT); |
| | | |
| | | String[] title = new String[numColumns]; |
| | | Arrays.fill(title, ""); |
| | | title[0] = "Throughput"; |
| | | title[2] = "Response Time"; |
| | | int[] span = new int[numColumns]; |
| | | span[0] = 2; |
| | | span[1] = 0; |
| | | span[2] = 2 + this.percentiles.size(); |
| | | Arrays.fill(span, 3, 4 + this.percentiles.size(), 0); |
| | | Arrays.fill(span, 4 + this.percentiles.size(), span.length, 1); |
| | | printer.addTitle(title, span); |
| | | title = new String[numColumns]; |
| | | Arrays.fill(title, ""); |
| | | title[0] = "(ops/second)"; |
| | | title[2] = "(milliseconds)"; |
| | | printer.addTitle(title, span); |
| | | title = new String[numColumns]; |
| | | title[0] = "recent"; |
| | | title[1] = "average"; |
| | | title[2] = "recent"; |
| | | title[3] = "average"; |
| | | int i = 4; |
| | | for (final Double percentile : this.percentiles) |
| | | { |
| | | title[i++] = Double.toString(100.0 - percentile) + "%"; |
| | | } |
| | | title[i++] = "err/sec"; |
| | | if (isAsync) |
| | | { |
| | | title[i++] = "req/res"; |
| | | } |
| | | for (final String column : additionalColumns) |
| | | { |
| | | title[i++] = column; |
| | | } |
| | | span = new int[numColumns]; |
| | | Arrays.fill(span, 1); |
| | | printer.addTitle(title, span); |
| | | printer.printTitle(); |
| | | } |
| | | else |
| | | { |
| | | app.getOutputStream().print("Time (seconds)"); |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Recent throughput (ops/second)"); |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Average throughput (ops/second)"); |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Recent response time (milliseconds)"); |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Average response time (milliseconds)"); |
| | | for (final Double percentile : this.percentiles) |
| | | { |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print(Double.toString(100.0 - percentile)); |
| | | app.getOutputStream().print("% response time (milliseconds)"); |
| | | } |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Errors/second"); |
| | | if (isAsync) |
| | | { |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print("Requests/response"); |
| | | } |
| | | for (final String column : additionalColumns) |
| | | { |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print(column); |
| | | } |
| | | app.getOutputStream().println(); |
| | | printer = null; |
| | | } |
| | | |
| | | final String[] strings = new String[numColumns]; |
| | | |
| | | final long startTime = System.currentTimeMillis(); |
| | | long statTime = startTime; |
| | | long gcDuration = 0; |
| | | for (final GarbageCollectorMXBean bean : beans) |
| | | { |
| | | gcDuration += bean.getCollectionTime(); |
| | | } |
| | | while (!stopRequested) |
| | | { |
| | | try |
| | | { |
| | | sleep(statsInterval); |
| | | } |
| | | catch (final InterruptedException ie) |
| | | { |
| | | // Ignore. |
| | | } |
| | | |
| | | lastStatTime = statTime; |
| | | statTime = System.currentTimeMillis(); |
| | | |
| | | lastGCDuration = gcDuration; |
| | | gcDuration = 0; |
| | | for (final GarbageCollectorMXBean bean : beans) |
| | | { |
| | | gcDuration += bean.getCollectionTime(); |
| | | } |
| | | |
| | | operationCount = operationRecentCount.getAndSet(0); |
| | | successCount = successRecentCount.getAndSet(0); |
| | | failedCount = failedRecentCount.getAndSet(0); |
| | | waitTime = waitRecentTime.getAndSet(0); |
| | | |
| | | final int resultCount = successCount + failedCount; |
| | | |
| | | totalOperationCount += operationCount; |
| | | totalSuccessCount += successCount; |
| | | totalFailedCount += failedCount; |
| | | totalWaitTime += waitTime; |
| | | |
| | | final long totalResultCount = totalSuccessCount + totalFailedCount; |
| | | |
| | | recentDuration = statTime - lastStatTime; |
| | | averageDuration = statTime - startTime; |
| | | recentDuration -= gcDuration - lastGCDuration; |
| | | averageDuration -= gcDuration; |
| | | recentDuration /= 1000.0; |
| | | averageDuration /= 1000.0; |
| | | |
| | | strings[0] = String.format("%.1f", resultCount / recentDuration); |
| | | strings[1] = String.format("%.1f", totalResultCount / averageDuration); |
| | | |
| | | if (resultCount > 0) |
| | | { |
| | | strings[2] = String.format("%.3f", |
| | | (waitTime - (gcDuration - lastGCDuration)) / (double) resultCount |
| | | / 1000000.0); |
| | | } |
| | | else |
| | | { |
| | | strings[2] = "-"; |
| | | } |
| | | |
| | | if (totalResultCount > 0) |
| | | { |
| | | strings[3] = String.format("%.3f", (totalWaitTime - gcDuration) |
| | | / (double) totalResultCount / 1000000.0); |
| | | } |
| | | else |
| | | { |
| | | strings[3] = "-"; |
| | | } |
| | | |
| | | boolean changed = false; |
| | | etimes = eTimeBuffer.getAndSet(etimes); |
| | | final int appendLength = Math.min(array.remaining(), etimes.size()); |
| | | if (appendLength > 0) |
| | | { |
| | | array.append(etimes, appendLength); |
| | | for (int i = array.size - appendLength; i < array.size; i++) |
| | | { |
| | | array.siftUp(0, i); |
| | | } |
| | | changed = true; |
| | | } |
| | | |
| | | // Our window buffer is now full. Replace smallest with anything |
| | | // larger and re-heapify |
| | | for (int i = appendLength; i < etimes.size(); i++) |
| | | { |
| | | if (etimes.get(i) > array.get(0)) |
| | | { |
| | | array.set(0, etimes.get(i)); |
| | | array.siftDown(0, array.size() - 1); |
| | | changed = true; |
| | | } |
| | | } |
| | | etimes.clear(); |
| | | |
| | | if (changed) |
| | | { |
| | | // Perform heapsort |
| | | int i = array.size() - 1; |
| | | while (i > 0) |
| | | { |
| | | array.swap(i, 0); |
| | | array.siftDown(0, i - 1); |
| | | i--; |
| | | } |
| | | array.reverse(); |
| | | } |
| | | |
| | | // Now everything is ordered from smallest to largest |
| | | int index; |
| | | int i = 4; |
| | | for (final Double percent : percentiles) |
| | | { |
| | | if (array.size() <= 0) |
| | | { |
| | | strings[i++] = "-"; |
| | | } |
| | | else |
| | | { |
| | | index = array.size() |
| | | - (int) Math.floor((percent / 100.0) * totalResultCount) - 1; |
| | | if (index < 0) |
| | | { |
| | | strings[i++] = String.format("*%.3f", array.get(0) / 1000000.0); |
| | | } |
| | | else |
| | | { |
| | | strings[i++] = String |
| | | .format("%.3f", array.get(index) / 1000000.0); |
| | | } |
| | | } |
| | | } |
| | | strings[i++] = String.format("%.1f", failedCount / recentDuration); |
| | | if (isAsync) |
| | | { |
| | | if (resultCount > 0) |
| | | { |
| | | strings[i++] = String.format("%.1f", (double) operationCount |
| | | / resultCount); |
| | | } |
| | | else |
| | | { |
| | | strings[i++] = "-"; |
| | | } |
| | | } |
| | | for (final String column : getAdditionalColumns()) |
| | | { |
| | | strings[i++] = column; |
| | | } |
| | | |
| | | if (printer != null) |
| | | { |
| | | printer.printRow(strings); |
| | | } |
| | | else |
| | | { |
| | | // Script-friendly. |
| | | app.getOutputStream().print(averageDuration); |
| | | for (final String s : strings) |
| | | { |
| | | app.getOutputStream().print(","); |
| | | app.getOutputStream().print(s); |
| | | } |
| | | app.getOutputStream().println(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | String[] getAdditionalColumns() |
| | | { |
| | | return EMPTY_STRINGS; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Statistics update result handler implementation. |
| | | * |
| | | * @param <S> |
| | | * The type of expected result. |
| | | */ |
| | | class UpdateStatsResultHandler<S extends Result> implements ResultHandler<S> |
| | | { |
| | | private final long startTime; |
| | | private final AsynchronousConnection connection; |
| | | private final ConnectionWorker worker; |
| | | |
| | | |
| | | |
| | | UpdateStatsResultHandler(final long startTime, |
| | | final AsynchronousConnection connection, final ConnectionWorker worker) |
| | | { |
| | | this.startTime = startTime; |
| | | this.connection = connection; |
| | | this.worker = worker; |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleErrorResult(final ErrorResultException error) |
| | | { |
| | | failedRecentCount.getAndIncrement(); |
| | | updateStats(); |
| | | |
| | | if (app.isVerbose()) |
| | | { |
| | | app.println(LocalizableMessage.raw(error.getResult().toString())); |
| | | } |
| | | |
| | | worker.operationCompleted(connection); |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleResult(final S result) |
| | | { |
| | | successRecentCount.getAndIncrement(); |
| | | updateStats(); |
| | | worker.operationCompleted(connection); |
| | | } |
| | | |
| | | |
| | | |
| | | private void updateStats() |
| | | { |
| | | final long eTime = System.nanoTime() - startTime; |
| | | waitRecentTime.getAndAdd(eTime); |
| | | synchronized (this) |
| | | { |
| | | final ReversableArray array = eTimeBuffer.get(); |
| | | if (array.remaining() == 0) |
| | | { |
| | | array.set(array.size() - 1, eTime); |
| | | } |
| | | else |
| | | { |
| | | array.append(eTime); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Worker thread base implementation. |
| | | */ |
| | | abstract class WorkerThread extends Thread |
| | | { |
| | | private int count; |
| | | |
| | | private final AsynchronousConnection connection; |
| | | |
| | | private final ConnectionFactory connectionFactory; |
| | | |
| | | |
| | | |
| | | WorkerThread(final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | super("Worker Thread"); |
| | | this.connection = connection; |
| | | this.connectionFactory = connectionFactory; |
| | | } |
| | | |
| | | |
| | | |
| | | public abstract FutureResult<?> performOperation( |
| | | AsynchronousConnection connection, DataSource[] dataSources, |
| | | long startTime); |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void run() |
| | | { |
| | | FutureResult<?> future; |
| | | AsynchronousConnection connection; |
| | | |
| | | final double targetTimeInMS = |
| | | (1.0 / (targetThroughput / (double) (numConcurrentTasks * numConnections))) * 1000.0; |
| | | double sleepTimeInMS = 0; |
| | | long start; |
| | | while (!stopRequested && !(maxIterations > 0 && count >= maxIterations)) |
| | | { |
| | | if (this.connection == null) |
| | | { |
| | | try |
| | | { |
| | | connection = connectionFactory.getAsynchronousConnection(null) |
| | | .get(); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // Ignore and check stop requested |
| | | continue; |
| | | } |
| | | catch (final ErrorResultException e) |
| | | { |
| | | app.println(LocalizableMessage.raw(e.getResult() |
| | | .getDiagnosticMessage())); |
| | | if (e.getCause() != null && app.isVerbose()) |
| | | { |
| | | e.getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | stopRequested = true; |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | connection = this.connection; |
| | | if (!noRebind |
| | | && connection instanceof AuthenticatedAsynchronousConnection) |
| | | { |
| | | final AuthenticatedAsynchronousConnection ac = |
| | | (AuthenticatedAsynchronousConnection) connection; |
| | | try |
| | | { |
| | | ac.rebind(null).get(); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // Ignore and check stop requested |
| | | continue; |
| | | } |
| | | catch (final ErrorResultException e) |
| | | { |
| | | app.println(LocalizableMessage.raw(e.getResult().toString())); |
| | | if (e.getCause() != null && app.isVerbose()) |
| | | { |
| | | e.getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | stopRequested = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | start = System.nanoTime(); |
| | | future = performOperation(connection, dataSources.get(), start); |
| | | operationRecentCount.getAndIncrement(); |
| | | count++; |
| | | if (!isAsync) |
| | | { |
| | | try |
| | | { |
| | | future.get(); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // Ignore and check stop requested |
| | | continue; |
| | | } |
| | | catch (final ErrorResultException e) |
| | | { |
| | | if (e.getCause() instanceof IOException) |
| | | { |
| | | e.getCause().printStackTrace(app.getErrorStream()); |
| | | stopRequested = true; |
| | | break; |
| | | } |
| | | // Ignore. Handled by result handler |
| | | } |
| | | finally |
| | | { |
| | | if (this.connection == null) |
| | | { |
| | | connection.close(); |
| | | } |
| | | } |
| | | } |
| | | if (targetThroughput > 0) |
| | | { |
| | | try |
| | | { |
| | | if (sleepTimeInMS > 1) |
| | | { |
| | | sleep((long) Math.floor(sleepTimeInMS)); |
| | | } |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | sleepTimeInMS += targetTimeInMS |
| | | - ((System.nanoTime() - start) / 1000000.0); |
| | | if (sleepTimeInMS < -60000) |
| | | { |
| | | // If we fall behind by 60 seconds, just forget about |
| | | // catching up |
| | | sleepTimeInMS = -60000; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static class ReversableArray |
| | | { |
| | | private final long[] array; |
| | | |
| | | private boolean reversed; |
| | | |
| | | private int size; |
| | | |
| | | |
| | | |
| | | public ReversableArray(final int capacity) |
| | | { |
| | | this.array = new long[capacity]; |
| | | } |
| | | |
| | | |
| | | |
| | | public void append(final long value) |
| | | { |
| | | if (size == array.length) |
| | | { |
| | | throw new IndexOutOfBoundsException(); |
| | | } |
| | | |
| | | if (!reversed) |
| | | { |
| | | array[size] = value; |
| | | } |
| | | else |
| | | { |
| | | System.arraycopy(array, 0, array, 1, size); |
| | | array[0] = value; |
| | | } |
| | | size++; |
| | | } |
| | | |
| | | |
| | | |
| | | public void append(final ReversableArray a, final int length) |
| | | { |
| | | if (length > a.size() || length > remaining()) |
| | | { |
| | | throw new IndexOutOfBoundsException(); |
| | | } |
| | | if (!reversed) |
| | | { |
| | | System.arraycopy(a.array, 0, array, size, length); |
| | | } |
| | | else |
| | | { |
| | | System.arraycopy(array, 0, array, length, size); |
| | | System.arraycopy(a.array, 0, array, 0, length); |
| | | } |
| | | size += length; |
| | | } |
| | | |
| | | |
| | | |
| | | public void clear() |
| | | { |
| | | size = 0; |
| | | } |
| | | |
| | | |
| | | |
| | | public long get(final int index) |
| | | { |
| | | if (index >= size) |
| | | { |
| | | throw new IndexOutOfBoundsException(); |
| | | } |
| | | if (!reversed) |
| | | { |
| | | return array[index]; |
| | | } |
| | | else |
| | | { |
| | | return array[size - index - 1]; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public int remaining() |
| | | { |
| | | return array.length - size; |
| | | } |
| | | |
| | | |
| | | |
| | | public void reverse() |
| | | { |
| | | reversed = !reversed; |
| | | } |
| | | |
| | | |
| | | |
| | | public void set(final int index, final long value) |
| | | { |
| | | if (index >= size) |
| | | { |
| | | throw new IndexOutOfBoundsException(); |
| | | } |
| | | if (!reversed) |
| | | { |
| | | array[index] = value; |
| | | } |
| | | else |
| | | { |
| | | array[size - index - 1] = value; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void siftDown(final int start, final int end) |
| | | { |
| | | int root = start; |
| | | int child; |
| | | while (root * 2 + 1 <= end) |
| | | { |
| | | child = root * 2 + 1; |
| | | if (child + 1 <= end && get(child) > get(child + 1)) |
| | | { |
| | | child = child + 1; |
| | | } |
| | | if (get(root) > get(child)) |
| | | { |
| | | swap(root, child); |
| | | root = child; |
| | | } |
| | | else |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void siftUp(final int start, final int end) |
| | | { |
| | | int child = end; |
| | | int parent; |
| | | while (child > start) |
| | | { |
| | | parent = (int) Math.floor((child - 1) / 2.0); |
| | | if (get(parent) > get(child)) |
| | | { |
| | | swap(parent, child); |
| | | child = parent; |
| | | } |
| | | else |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public int size() |
| | | { |
| | | return size; |
| | | } |
| | | |
| | | |
| | | |
| | | private void swap(final int i, final int i2) |
| | | { |
| | | final long temp = get(i); |
| | | set(i, get(i2)); |
| | | set(i2, temp); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final String[] EMPTY_STRINGS = new String[0]; |
| | | |
| | | private final AtomicInteger operationRecentCount = new AtomicInteger(); |
| | | |
| | | protected final AtomicInteger successRecentCount = new AtomicInteger(); |
| | | |
| | | protected final AtomicInteger failedRecentCount = new AtomicInteger(); |
| | | |
| | | private final AtomicLong waitRecentTime = new AtomicLong(); |
| | | |
| | | private final AtomicReference<ReversableArray> eTimeBuffer = new AtomicReference<ReversableArray>( |
| | | new ReversableArray(100000)); |
| | | |
| | | private final ConsoleApplication app; |
| | | |
| | | private DataSource[] dataSourcePrototypes; |
| | | |
| | | // Thread local copies of the data sources |
| | | private final ThreadLocal<DataSource[]> dataSources = new ThreadLocal<DataSource[]>() |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected DataSource[] initialValue() |
| | | { |
| | | final DataSource[] prototypes = getDataSources(); |
| | | final int sz = prototypes.length; |
| | | final DataSource[] threadLocalCopy = new DataSource[sz]; |
| | | for (int i = 0; i < sz; i++) |
| | | { |
| | | threadLocalCopy[i] = prototypes[i].duplicate(); |
| | | } |
| | | return threadLocalCopy; |
| | | } |
| | | |
| | | }; |
| | | |
| | | private volatile boolean stopRequested; |
| | | |
| | | private int numConcurrentTasks; |
| | | |
| | | private int numConnections; |
| | | |
| | | private int targetThroughput; |
| | | |
| | | private int maxIterations; |
| | | |
| | | private boolean isAsync; |
| | | |
| | | private boolean noRebind; |
| | | |
| | | private int statsInterval; |
| | | |
| | | private double targetTimeInMS; |
| | | |
| | | private final IntegerArgument numConcurrentTasksArgument; |
| | | |
| | | private final IntegerArgument maxIterationsArgument; |
| | | |
| | | private final IntegerArgument statsIntervalArgument; |
| | | |
| | | private final IntegerArgument targetThroughputArgument; |
| | | |
| | | private final IntegerArgument numConnectionsArgument; |
| | | |
| | | private final IntegerArgument percentilesArgument; |
| | | |
| | | private final BooleanArgument keepConnectionsOpen; |
| | | |
| | | private final BooleanArgument noRebindArgument; |
| | | |
| | | private final BooleanArgument asyncArgument; |
| | | |
| | | private final StringArgument arguments; |
| | | |
| | | |
| | | |
| | | PerformanceRunner(final ArgumentParser argParser, |
| | | final ConsoleApplication app, final boolean neverRebind, |
| | | final boolean neverAsynchronous, final boolean alwaysSingleThreaded) |
| | | throws ArgumentException |
| | | { |
| | | this.app = app; |
| | | numConcurrentTasksArgument = new IntegerArgument("numConcurrentTasks", 't', |
| | | "numConcurrentTasks", false, false, true, |
| | | LocalizableMessage.raw("{numConcurrentTasks}"), 1, null, true, 1, |
| | | false, 0, |
| | | LocalizableMessage.raw("Number of concurrent tasks per connection")); |
| | | numConcurrentTasksArgument.setPropertyName("numConcurrentTasks"); |
| | | if (!alwaysSingleThreaded) |
| | | { |
| | | argParser.addArgument(numConcurrentTasksArgument); |
| | | } |
| | | else |
| | | { |
| | | numConcurrentTasksArgument.addValue("1"); |
| | | } |
| | | |
| | | numConnectionsArgument = new IntegerArgument("numConnections", 'c', |
| | | "numConnections", false, false, true, |
| | | LocalizableMessage.raw("{numConnections}"), 1, null, true, 1, false, 0, |
| | | LocalizableMessage.raw("Number of connections")); |
| | | numConnectionsArgument.setPropertyName("numConnections"); |
| | | argParser.addArgument(numConnectionsArgument); |
| | | |
| | | maxIterationsArgument = new IntegerArgument("maxIterations", 'm', |
| | | "maxIterations", false, false, true, |
| | | LocalizableMessage.raw("{maxIterations}"), 0, null, |
| | | LocalizableMessage.raw("Max iterations, 0 for unlimited")); |
| | | maxIterationsArgument.setPropertyName("maxIterations"); |
| | | argParser.addArgument(maxIterationsArgument); |
| | | |
| | | statsIntervalArgument = new IntegerArgument("statInterval", 'i', |
| | | "statInterval", false, false, true, |
| | | LocalizableMessage.raw("{statInterval}"), 5, null, true, 1, false, 0, |
| | | LocalizableMessage |
| | | .raw("Display results each specified number of seconds")); |
| | | statsIntervalArgument.setPropertyName("statInterval"); |
| | | argParser.addArgument(statsIntervalArgument); |
| | | |
| | | targetThroughputArgument = new IntegerArgument("targetThroughput", 'M', |
| | | "targetThroughput", false, false, true, |
| | | LocalizableMessage.raw("{targetThroughput}"), 0, null, |
| | | LocalizableMessage.raw("Target average throughput to achieve")); |
| | | targetThroughputArgument.setPropertyName("targetThroughput"); |
| | | argParser.addArgument(targetThroughputArgument); |
| | | |
| | | percentilesArgument = new IntegerArgument("percentile", 'e', "percentile", |
| | | false, true, LocalizableMessage.raw("{percentile}"), true, 0, true, |
| | | 100, LocalizableMessage.raw("Calculate max response time for a " |
| | | + "percentile of operations")); |
| | | percentilesArgument.setPropertyName("percentile"); |
| | | percentilesArgument.setMultiValued(true); |
| | | argParser.addArgument(percentilesArgument); |
| | | |
| | | keepConnectionsOpen = new BooleanArgument("keepConnectionsOpen", 'f', |
| | | "keepConnectionsOpen", LocalizableMessage.raw("Keep connections open")); |
| | | keepConnectionsOpen.setPropertyName("keepConnectionsOpen"); |
| | | argParser.addArgument(keepConnectionsOpen); |
| | | |
| | | noRebindArgument = new BooleanArgument("noRebind", 'F', "noRebind", |
| | | LocalizableMessage.raw("Keep connections open and don't rebind")); |
| | | noRebindArgument.setPropertyName("noRebind"); |
| | | if (!neverRebind) |
| | | { |
| | | argParser.addArgument(noRebindArgument); |
| | | } |
| | | else |
| | | { |
| | | noRebindArgument.addValue(String.valueOf(true)); |
| | | } |
| | | |
| | | asyncArgument = new BooleanArgument("asynchronous", 'A', "asynchronous", |
| | | LocalizableMessage.raw("Use asynchronous mode and don't " |
| | | + "wait for results before sending the next request")); |
| | | asyncArgument.setPropertyName("asynchronous"); |
| | | if (!neverAsynchronous) |
| | | { |
| | | argParser.addArgument(asyncArgument); |
| | | } |
| | | |
| | | arguments = new StringArgument( |
| | | "argument", |
| | | 'g', |
| | | "argument", |
| | | false, |
| | | true, |
| | | true, |
| | | LocalizableMessage.raw("{generator function or static string}"), |
| | | null, |
| | | null, |
| | | LocalizableMessage.raw("Argument used to evaluate the Java " |
| | | + "style format strings in program parameters (ie. Base DN, " |
| | | + "Search Filter). The set of all arguments provided form the " |
| | | + "the argument list in order. Besides static string " |
| | | + "arguments, they can be generated per iteration with the " |
| | | + "following functions: " + StaticUtils.EOL + DataSource.getUsage())); |
| | | argParser.addArgument(arguments); |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleConnectionClosed() |
| | | { |
| | | // Ignore |
| | | } |
| | | |
| | | |
| | | |
| | | public synchronized void handleConnectionError( |
| | | final boolean isDisconnectNotification, final ErrorResultException error) |
| | | { |
| | | if (!stopRequested) |
| | | { |
| | | app.println(LocalizableMessage.raw("Error occurred on one or more " |
| | | + "connections: " + error.getResult().toString())); |
| | | if (error.getCause() != null && app.isVerbose()) |
| | | { |
| | | error.getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | stopRequested = true; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleUnsolicitedNotification(final ExtendedResult notification) |
| | | { |
| | | // Ignore |
| | | } |
| | | |
| | | |
| | | |
| | | public final void validate() throws ArgumentException |
| | | { |
| | | numConnections = numConnectionsArgument.getIntValue(); |
| | | numConcurrentTasks = numConcurrentTasksArgument.getIntValue(); |
| | | maxIterations = maxIterationsArgument.getIntValue() / numConnections; |
| | | statsInterval = statsIntervalArgument.getIntValue() * 1000; |
| | | targetThroughput = targetThroughputArgument.getIntValue(); |
| | | |
| | | isAsync = asyncArgument.isPresent(); |
| | | noRebind = noRebindArgument.isPresent(); |
| | | |
| | | if (!noRebindArgument.isPresent() && this.numConcurrentTasks > 1) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw("--" |
| | | + noRebindArgument.getLongIdentifier() + " must be used if --" |
| | | + numConcurrentTasksArgument.getLongIdentifier() + " is > 1")); |
| | | } |
| | | |
| | | if (!noRebindArgument.isPresent() && asyncArgument.isPresent()) |
| | | { |
| | | throw new ArgumentException(LocalizableMessage.raw("--" |
| | | + noRebindArgument.getLongIdentifier() |
| | | + " must be used when using --" + asyncArgument.getLongIdentifier())); |
| | | } |
| | | |
| | | dataSourcePrototypes = DataSource.parse(arguments.getValues()); |
| | | |
| | | targetTimeInMS = |
| | | (1.0 / (targetThroughput / (double) (numConcurrentTasks * numConnections))) * 1000.0; |
| | | } |
| | | |
| | | |
| | | |
| | | final DataSource[] getDataSources() |
| | | { |
| | | if (dataSourcePrototypes == null) |
| | | { |
| | | throw new IllegalStateException( |
| | | "dataSources are null - validate() must be called first"); |
| | | } |
| | | return dataSourcePrototypes; |
| | | } |
| | | |
| | | |
| | | |
| | | abstract ConnectionWorker newConnectionWorker( |
| | | final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory); |
| | | |
| | | |
| | | |
| | | abstract StatsThread newStatsThread(); |
| | | |
| | | |
| | | |
| | | final int run(final ConnectionFactory connectionFactory) |
| | | { |
| | | final List<ConnectionWorker> workers = new ArrayList<ConnectionWorker>(); |
| | | final List<AsynchronousConnection> connections = new ArrayList<AsynchronousConnection>(); |
| | | |
| | | AsynchronousConnection connection = null; |
| | | try |
| | | { |
| | | for (int i = 0; i < numConnections; i++) |
| | | { |
| | | if (keepConnectionsOpen.isPresent() || noRebindArgument.isPresent()) |
| | | { |
| | | connection = connectionFactory.getAsynchronousConnection(null).get(); |
| | | connection.addConnectionEventListener(this); |
| | | connections.add(connection); |
| | | } |
| | | final ConnectionWorker worker = newConnectionWorker(connection, |
| | | connectionFactory); |
| | | workers.add(worker); |
| | | worker.startWork(); |
| | | } |
| | | |
| | | final Thread statsThread = newStatsThread(); |
| | | statsThread.start(); |
| | | |
| | | for (final ConnectionWorker w : workers) |
| | | { |
| | | w.waitFor(); |
| | | } |
| | | stopRequested = true; |
| | | statsThread.join(); |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | stopRequested = true; |
| | | } |
| | | catch (final ErrorResultException e) |
| | | { |
| | | stopRequested = true; |
| | | app.println(LocalizableMessage.raw(e.getResult().getDiagnosticMessage())); |
| | | } |
| | | finally |
| | | { |
| | | for (final AsynchronousConnection c : connections) |
| | | { |
| | | c.close(); |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.security.KeyStore; |
| | | import java.security.KeyStoreException; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | |
| | | import javax.net.ssl.TrustManager; |
| | | import javax.net.ssl.TrustManagerFactory; |
| | | import javax.net.ssl.X509TrustManager; |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A trust manager which prompts the user for the length of time that they would |
| | | * like to trust a server certificate. |
| | | */ |
| | | final class PromptingTrustManager implements X509TrustManager |
| | | { |
| | | /** |
| | | * Enumeration description server certificate trust option. |
| | | */ |
| | | private static enum TrustOption |
| | | { |
| | | UNTRUSTED(1, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_NO.get()), SESSION( |
| | | 2, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_SESSION.get()), PERMANENT( |
| | | 3, INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_ALWAYS.get()), CERTIFICATE_DETAILS( |
| | | 4, INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_DETAILS.get()); |
| | | |
| | | private Integer choice; |
| | | |
| | | private LocalizableMessage msg; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Private constructor. |
| | | * |
| | | * @param i |
| | | * the menu return value. |
| | | * @param msg |
| | | * the message message. |
| | | */ |
| | | private TrustOption(final int i, final LocalizableMessage msg) |
| | | { |
| | | choice = i; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the choice number. |
| | | * |
| | | * @return the attribute name. |
| | | */ |
| | | Integer getChoice() |
| | | { |
| | | return choice; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Return the menu message. |
| | | * |
| | | * @return the menu message. |
| | | */ |
| | | LocalizableMessage getMenuMessage() |
| | | { |
| | | return msg; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | static private final Logger LOG = Logger |
| | | .getLogger(PromptingTrustManager.class.getName()); |
| | | |
| | | static private final String DEFAULT_PATH = System.getProperty("user.home") |
| | | + File.separator + ".opends" + File.separator + "keystore"; |
| | | |
| | | static private final char[] DEFAULT_PASSWORD = "OpenDS".toCharArray(); |
| | | |
| | | private final KeyStore inMemoryTrustStore; |
| | | |
| | | private final KeyStore onDiskTrustStore; |
| | | |
| | | private final X509TrustManager inMemoryTrustManager; |
| | | |
| | | private final X509TrustManager onDiskTrustManager; |
| | | |
| | | private final X509TrustManager nestedTrustManager; |
| | | |
| | | private final ConsoleApplication app; |
| | | |
| | | |
| | | |
| | | PromptingTrustManager(final ConsoleApplication app, |
| | | final String acceptedStorePath, final X509TrustManager sourceTrustManager) |
| | | throws KeyStoreException, IOException, NoSuchAlgorithmException, |
| | | CertificateException |
| | | { |
| | | Validator.ensureNotNull(app, acceptedStorePath); |
| | | this.app = app; |
| | | this.nestedTrustManager = sourceTrustManager; |
| | | inMemoryTrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| | | onDiskTrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| | | |
| | | final File onDiskTrustStorePath = new File(acceptedStorePath); |
| | | inMemoryTrustStore.load(null, null); |
| | | if (!onDiskTrustStorePath.exists()) |
| | | { |
| | | onDiskTrustStore.load(null, null); |
| | | } |
| | | else |
| | | { |
| | | final FileInputStream fos = new FileInputStream(onDiskTrustStorePath); |
| | | try |
| | | { |
| | | onDiskTrustStore.load(fos, DEFAULT_PASSWORD); |
| | | } |
| | | finally |
| | | { |
| | | fos.close(); |
| | | } |
| | | } |
| | | final TrustManagerFactory tmf = TrustManagerFactory |
| | | .getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| | | |
| | | tmf.init(inMemoryTrustStore); |
| | | X509TrustManager x509tm = null; |
| | | for (final TrustManager tm : tmf.getTrustManagers()) |
| | | { |
| | | if (tm instanceof X509TrustManager) |
| | | { |
| | | x509tm = (X509TrustManager) tm; |
| | | break; |
| | | } |
| | | } |
| | | if (x509tm == null) |
| | | { |
| | | throw new NoSuchAlgorithmException(); |
| | | } |
| | | this.inMemoryTrustManager = x509tm; |
| | | |
| | | tmf.init(onDiskTrustStore); |
| | | x509tm = null; |
| | | for (final TrustManager tm : tmf.getTrustManagers()) |
| | | { |
| | | if (tm instanceof X509TrustManager) |
| | | { |
| | | x509tm = (X509TrustManager) tm; |
| | | break; |
| | | } |
| | | } |
| | | if (x509tm == null) |
| | | { |
| | | throw new NoSuchAlgorithmException(); |
| | | } |
| | | this.onDiskTrustManager = x509tm; |
| | | } |
| | | |
| | | |
| | | |
| | | PromptingTrustManager(final ConsoleApplication app, |
| | | final X509TrustManager sourceTrustManager) throws KeyStoreException, |
| | | IOException, NoSuchAlgorithmException, CertificateException |
| | | { |
| | | this(app, DEFAULT_PATH, sourceTrustManager); |
| | | } |
| | | |
| | | |
| | | |
| | | public void checkClientTrusted(final X509Certificate[] x509Certificates, |
| | | final String s) throws CertificateException |
| | | { |
| | | try |
| | | { |
| | | inMemoryTrustManager.checkClientTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce1) |
| | | { |
| | | try |
| | | { |
| | | onDiskTrustManager.checkClientTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce2) |
| | | { |
| | | if (nestedTrustManager != null) |
| | | { |
| | | try |
| | | { |
| | | nestedTrustManager.checkClientTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce3) |
| | | { |
| | | checkManuallyTrusted(x509Certificates, ce3); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | checkManuallyTrusted(x509Certificates, ce1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void checkServerTrusted(final X509Certificate[] x509Certificates, |
| | | final String s) throws CertificateException |
| | | { |
| | | try |
| | | { |
| | | inMemoryTrustManager.checkServerTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce1) |
| | | { |
| | | try |
| | | { |
| | | onDiskTrustManager.checkServerTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce2) |
| | | { |
| | | if (nestedTrustManager != null) |
| | | { |
| | | try |
| | | { |
| | | nestedTrustManager.checkServerTrusted(x509Certificates, s); |
| | | } |
| | | catch (final Exception ce3) |
| | | { |
| | | checkManuallyTrusted(x509Certificates, ce3); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | checkManuallyTrusted(x509Certificates, ce1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public X509Certificate[] getAcceptedIssuers() |
| | | { |
| | | if (nestedTrustManager != null) |
| | | { |
| | | return nestedTrustManager.getAcceptedIssuers(); |
| | | } |
| | | return new X509Certificate[0]; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * This method is called when the user accepted a certificate. |
| | | * |
| | | * @param chain |
| | | * the certificate chain accepted by the user. certificate. |
| | | */ |
| | | private void acceptCertificate(final X509Certificate[] chain, |
| | | final boolean permanent) |
| | | { |
| | | if (permanent) |
| | | { |
| | | LOG.log(Level.INFO, "Permanently accepting certificate chain to " |
| | | + "truststore"); |
| | | } |
| | | else |
| | | { |
| | | LOG.log(Level.INFO, "Accepting certificate chain for this session"); |
| | | } |
| | | |
| | | for (final X509Certificate aChain : chain) |
| | | { |
| | | try |
| | | { |
| | | final String alias = aChain.getSubjectDN().getName(); |
| | | inMemoryTrustStore.setCertificateEntry(alias, aChain); |
| | | if (permanent) |
| | | { |
| | | onDiskTrustStore.setCertificateEntry(alias, aChain); |
| | | } |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | LOG.log(Level.WARNING, "Error setting certificate to store: " + e |
| | | + "\nCert: " + aChain.toString()); |
| | | } |
| | | } |
| | | |
| | | if (permanent) |
| | | { |
| | | try |
| | | { |
| | | final File truststoreFile = new File(DEFAULT_PATH); |
| | | if (!truststoreFile.exists()) |
| | | { |
| | | createFile(truststoreFile); |
| | | } |
| | | final FileOutputStream fos = new FileOutputStream(truststoreFile); |
| | | onDiskTrustStore.store(fos, DEFAULT_PASSWORD); |
| | | fos.close(); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | LOG.log(Level.WARNING, "Error saving store to disk: " + e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicate if the certificate chain can be trusted. |
| | | * |
| | | * @param chain |
| | | * The certificate chain to validate certificate. |
| | | */ |
| | | private void checkManuallyTrusted(final X509Certificate[] chain, |
| | | final Exception exception) throws CertificateException |
| | | { |
| | | app.println(); |
| | | app.println(INFO_LDAP_CONN_PROMPT_SECURITY_SERVER_CERTIFICATE.get()); |
| | | app.println(); |
| | | for (final X509Certificate element : chain) |
| | | { |
| | | // Certificate DN |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_USER_DN |
| | | .get(element.getSubjectDN().toString())); |
| | | |
| | | // certificate validity |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_VALIDITY.get( |
| | | element.getNotBefore().toString(), element.getNotAfter().toString())); |
| | | |
| | | // certificate Issuer |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_ISSUER.get(element |
| | | .getIssuerDN().toString())); |
| | | |
| | | app.println(); |
| | | app.println(); |
| | | } |
| | | |
| | | app.println(); |
| | | app.println(INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION.get()); |
| | | app.println(); |
| | | |
| | | final Map<String, TrustOption> menuOptions = new HashMap<String, TrustOption>(); |
| | | for (final TrustOption t : TrustOption.values()) |
| | | { |
| | | menuOptions.put(t.getChoice().toString(), t); |
| | | |
| | | final LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | builder.append(t.getChoice()); |
| | | builder.append(") "); |
| | | builder.append(t.getMenuMessage()); |
| | | app.println(builder.toMessage(), 2 /* Indent options */); |
| | | } |
| | | |
| | | final TrustOption defaultTrustMethod = TrustOption.SESSION; |
| | | final LocalizableMessage promptMsg = INFO_MENU_PROMPT_SINGLE.get(); |
| | | |
| | | while (true) |
| | | { |
| | | app.println(); |
| | | String choice; |
| | | try |
| | | { |
| | | choice = app.readInput(promptMsg, defaultTrustMethod.getChoice() |
| | | .toString()); |
| | | } |
| | | catch (final CLIException e) |
| | | { |
| | | // What can we do here? |
| | | throw new CertificateException(exception); |
| | | } |
| | | finally |
| | | { |
| | | app.println(); |
| | | } |
| | | |
| | | final TrustOption option = menuOptions.get(choice.trim()); |
| | | if (option == null) |
| | | { |
| | | app.println(ERR_MENU_BAD_CHOICE_SINGLE.get()); |
| | | app.println(); |
| | | continue; |
| | | } |
| | | |
| | | switch (option) |
| | | { |
| | | case UNTRUSTED: |
| | | if (exception instanceof CertificateException) |
| | | { |
| | | throw (CertificateException) exception; |
| | | } |
| | | else |
| | | { |
| | | throw new CertificateException(exception); |
| | | } |
| | | case CERTIFICATE_DETAILS: |
| | | for (final X509Certificate aChain : chain) |
| | | { |
| | | app.println(); |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE.get(aChain |
| | | .toString())); |
| | | app.println(); |
| | | } |
| | | break; |
| | | default: // SESSION / PERMANENT. |
| | | // Update the trust manager with the new certificate |
| | | acceptCertificate(chain, option == TrustOption.PERMANENT); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean createFile(final File f) throws IOException |
| | | { |
| | | boolean success = false; |
| | | if (f != null) |
| | | { |
| | | final File parent = f.getParentFile(); |
| | | if (!parent.exists()) |
| | | { |
| | | parent.mkdirs(); |
| | | } |
| | | success = f.createNewFile(); |
| | | } |
| | | return success; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.filterExitCode; |
| | | |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import org.glassfish.grizzly.TransportFactory; |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.requests.SearchRequest; |
| | | import org.opends.sdk.responses.Result; |
| | | import org.opends.sdk.responses.SearchResultEntry; |
| | | import org.opends.sdk.responses.SearchResultReference; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A load generation tool that can be used to load a Directory Server with |
| | | * Search requests using one or more LDAP connections. |
| | | */ |
| | | public final class SearchRate extends ConsoleApplication |
| | | { |
| | | private final class SearchPerformanceRunner extends PerformanceRunner |
| | | { |
| | | private final class SearchStatsHandler extends |
| | | UpdateStatsResultHandler<Result> implements SearchResultHandler |
| | | { |
| | | private SearchStatsHandler(final long startTime, |
| | | final AsynchronousConnection connection, final ConnectionWorker worker) |
| | | { |
| | | super(startTime, connection, worker); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public boolean handleEntry(final SearchResultEntry entry) |
| | | { |
| | | entryRecentCount.getAndIncrement(); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public boolean handleReference(final SearchResultReference reference) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private final class SearchStatsThread extends StatsThread |
| | | { |
| | | private final String[] extraColumn; |
| | | |
| | | |
| | | |
| | | private SearchStatsThread() |
| | | { |
| | | super(new String[] { "Entries/Srch" }); |
| | | extraColumn = new String[1]; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | String[] getAdditionalColumns() |
| | | { |
| | | final int entryCount = entryRecentCount.getAndSet(0); |
| | | if (successCount > 0) |
| | | { |
| | | extraColumn[0] = String.format("%.1f", (double) entryCount |
| | | / successCount); |
| | | } |
| | | else |
| | | { |
| | | extraColumn[0] = String.format("%.1f", 0.0); |
| | | } |
| | | return extraColumn; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private final class SearchWorkerThread extends ConnectionWorker |
| | | { |
| | | private SearchRequest sr; |
| | | |
| | | private Object[] data; |
| | | |
| | | |
| | | |
| | | private SearchWorkerThread(final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | super(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public FutureResult<?> performOperation( |
| | | final AsynchronousConnection connection, |
| | | final DataSource[] dataSources, final long startTime) |
| | | { |
| | | if (sr == null) |
| | | { |
| | | if (dataSources == null) |
| | | { |
| | | sr = Requests.newSearchRequest(baseDN, scope, filter, attributes); |
| | | } |
| | | else |
| | | { |
| | | data = DataSource.generateData(dataSources, data); |
| | | sr = Requests.newSearchRequest(String.format(baseDN, data), scope, |
| | | String.format(filter, data), attributes); |
| | | } |
| | | sr.setDereferenceAliasesPolicy(dereferencesAliasesPolicy); |
| | | } |
| | | else if (dataSources != null) |
| | | { |
| | | data = DataSource.generateData(dataSources, data); |
| | | sr.setFilter(String.format(filter, data)); |
| | | sr.setName(String.format(baseDN, data)); |
| | | } |
| | | return connection.search(sr, new SearchStatsHandler(startTime, |
| | | connection, this)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private String filter; |
| | | |
| | | private String baseDN; |
| | | |
| | | private SearchScope scope; |
| | | |
| | | private DereferenceAliasesPolicy dereferencesAliasesPolicy; |
| | | |
| | | private String[] attributes; |
| | | |
| | | |
| | | |
| | | private SearchPerformanceRunner(final ArgumentParser argParser, |
| | | final ConsoleApplication app) throws ArgumentException |
| | | { |
| | | super(argParser, app, false, false, false); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | ConnectionWorker newConnectionWorker( |
| | | final AsynchronousConnection connection, |
| | | final ConnectionFactory connectionFactory) |
| | | { |
| | | return new SearchWorkerThread(connection, connectionFactory); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | StatsThread newStatsThread() |
| | | { |
| | | return new SearchStatsThread(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The main method for SearchRate tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | */ |
| | | |
| | | public static void main(final String[] args) |
| | | { |
| | | final int retCode = mainSearchRate(args, System.in, System.out, System.err); |
| | | System.exit(filterExitCode(retCode)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the ldapsearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainSearchRate(final String[] args) |
| | | { |
| | | return mainSearchRate(args, System.in, System.out, System.err); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and uses that information to run |
| | | * the ldapsearch tool. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @param inStream |
| | | * The input stream to use for standard input, or <CODE>null</CODE> |
| | | * if standard input is not needed. |
| | | * @param outStream |
| | | * The output stream to use for standard output, or <CODE>null</CODE> |
| | | * if standard output is not needed. |
| | | * @param errStream |
| | | * The output stream to use for standard error, or <CODE>null</CODE> |
| | | * if standard error is not needed. |
| | | * @return The error code. |
| | | */ |
| | | |
| | | static int mainSearchRate(final String[] args, final InputStream inStream, |
| | | final OutputStream outStream, final OutputStream errStream) |
| | | |
| | | { |
| | | return new SearchRate(inStream, outStream, errStream).run(args); |
| | | } |
| | | |
| | | |
| | | |
| | | private BooleanArgument verbose; |
| | | |
| | | private BooleanArgument scriptFriendly; |
| | | |
| | | private final AtomicInteger entryRecentCount = new AtomicInteger(); |
| | | |
| | | |
| | | |
| | | private SearchRate(final InputStream in, final OutputStream out, |
| | | final OutputStream err) |
| | | { |
| | | super(in, out, err); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested advanced mode. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested advanced mode. |
| | | */ |
| | | @Override |
| | | public boolean isAdvancedMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested interactive behavior. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested interactive |
| | | * behavior. |
| | | */ |
| | | @Override |
| | | public boolean isInteractive() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not this console application is running in its |
| | | * menu-driven mode. This can be used to dictate whether output should go to |
| | | * the error stream or not. In addition, it may also dictate whether or not |
| | | * sub-menus should display a cancel option as well as a quit option. |
| | | * |
| | | * @return Returns <code>true</code> if this console application is running in |
| | | * its menu-driven mode. |
| | | */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested quiet output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested quiet output. |
| | | */ |
| | | @Override |
| | | public boolean isQuiet() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested script-friendly output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested script-friendly |
| | | * output. |
| | | */ |
| | | @Override |
| | | public boolean isScriptFriendly() |
| | | { |
| | | return scriptFriendly.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether or not the user has requested verbose output. |
| | | * |
| | | * @return Returns <code>true</code> if the user has requested verbose output. |
| | | */ |
| | | @Override |
| | | public boolean isVerbose() |
| | | { |
| | | return verbose.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | private int run(final String[] args) |
| | | { |
| | | // Create the command-line argument parser for use with this |
| | | // program. |
| | | final LocalizableMessage toolDescription = INFO_SEARCHRATE_TOOL_DESCRIPTION |
| | | .get(); |
| | | final ArgumentParser argParser = new ArgumentParser( |
| | | SearchRate.class.getName(), toolDescription, false, true, 1, 0, |
| | | "[filter format string] [attributes ...]"); |
| | | |
| | | ConnectionFactoryProvider connectionFactoryProvider; |
| | | ConnectionFactory connectionFactory; |
| | | SearchPerformanceRunner runner; |
| | | |
| | | StringArgument baseDN; |
| | | MultiChoiceArgument<SearchScope> searchScope; |
| | | MultiChoiceArgument<DereferenceAliasesPolicy> dereferencePolicy; |
| | | BooleanArgument showUsage; |
| | | StringArgument propertiesFileArgument; |
| | | BooleanArgument noPropertiesFileArgument; |
| | | |
| | | try |
| | | { |
| | | TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory()); |
| | | connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this); |
| | | runner = new SearchPerformanceRunner(argParser, this); |
| | | |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, |
| | | OPTION_LONG_PROP_FILE_PATH, false, false, true, |
| | | INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | argParser.addArgument(propertiesFileArgument); |
| | | argParser.setFilePropertiesArgument(propertiesFileArgument); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | argParser.addArgument(noPropertiesFileArgument); |
| | | argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); |
| | | |
| | | showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP, |
| | | OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get()); |
| | | argParser.addArgument(showUsage); |
| | | argParser.setUsageArgument(showUsage, getOutputStream()); |
| | | |
| | | baseDN = new StringArgument("baseDN", OPTION_SHORT_BASEDN, |
| | | OPTION_LONG_BASEDN, true, false, true, INFO_BASEDN_PLACEHOLDER.get(), |
| | | null, null, INFO_SEARCHRATE_TOOL_DESCRIPTION_BASEDN.get()); |
| | | baseDN.setPropertyName(OPTION_LONG_BASEDN); |
| | | argParser.addArgument(baseDN); |
| | | |
| | | searchScope = new MultiChoiceArgument<SearchScope>("searchScope", 's', |
| | | "searchScope", false, true, INFO_SEARCH_SCOPE_PLACEHOLDER.get(), |
| | | SearchScope.values(), false, |
| | | INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE.get()); |
| | | searchScope.setPropertyName("searchScope"); |
| | | searchScope.setDefaultValue(SearchScope.WHOLE_SUBTREE); |
| | | argParser.addArgument(searchScope); |
| | | |
| | | dereferencePolicy = new MultiChoiceArgument<DereferenceAliasesPolicy>( |
| | | "derefpolicy", 'a', "dereferencePolicy", false, true, |
| | | INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(), |
| | | DereferenceAliasesPolicy.values(), false, |
| | | INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY.get()); |
| | | dereferencePolicy.setPropertyName("dereferencePolicy"); |
| | | dereferencePolicy.setDefaultValue(DereferenceAliasesPolicy.NEVER); |
| | | argParser.addArgument(dereferencePolicy); |
| | | |
| | | verbose = new BooleanArgument("verbose", 'v', "verbose", |
| | | INFO_DESCRIPTION_VERBOSE.get()); |
| | | verbose.setPropertyName("verbose"); |
| | | argParser.addArgument(verbose); |
| | | |
| | | scriptFriendly = new BooleanArgument("scriptFriendly", 'S', |
| | | "scriptFriendly", INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()); |
| | | scriptFriendly.setPropertyName("scriptFriendly"); |
| | | argParser.addArgument(scriptFriendly); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | try |
| | | { |
| | | argParser.parseArguments(args); |
| | | |
| | | // If we should just display usage or version information, |
| | | // then print it and exit. |
| | | if (argParser.usageOrVersionDisplayed()) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | connectionFactory = connectionFactoryProvider |
| | | .getAuthenticatedConnectionFactory(); |
| | | runner.validate(); |
| | | } |
| | | catch (final ArgumentException ae) |
| | | { |
| | | final LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage()); |
| | | println(message); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | final List<String> attributes = new LinkedList<String>(); |
| | | final ArrayList<String> filterAndAttributeStrings = argParser |
| | | .getTrailingArguments(); |
| | | if (filterAndAttributeStrings.size() > 0) |
| | | { |
| | | // the list of trailing arguments should be structured as follow: |
| | | // the first trailing argument is |
| | | // considered the filter, the other as attributes. |
| | | runner.filter = filterAndAttributeStrings.remove(0); |
| | | // The rest are attributes |
| | | for (final String s : filterAndAttributeStrings) |
| | | { |
| | | attributes.add(s); |
| | | } |
| | | } |
| | | runner.attributes = attributes.toArray(new String[attributes.size()]); |
| | | runner.baseDN = baseDN.getValue(); |
| | | try |
| | | { |
| | | runner.scope = searchScope.getTypedValue(); |
| | | runner.dereferencesAliasesPolicy = dereferencePolicy.getTypedValue(); |
| | | } |
| | | catch (final ArgumentException ex1) |
| | | { |
| | | println(ex1.getMessageObject()); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | try |
| | | { |
| | | // Try it out to make sure the format string and data sources |
| | | // match. |
| | | final Object[] data = DataSource.generateData(runner.getDataSources(), |
| | | null); |
| | | String.format(runner.filter, data); |
| | | String.format(runner.baseDN, data); |
| | | } |
| | | catch (final Exception ex1) |
| | | { |
| | | println(LocalizableMessage.raw("Error formatting filter or base DN: " |
| | | + ex1.toString())); |
| | | return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); |
| | | } |
| | | |
| | | return runner.run(connectionFactory); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.LocalizableMessageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines an argument type that will accept any string value. |
| | | */ |
| | | final class StringArgument extends Argument |
| | | { |
| | | /** |
| | | * Creates a new string argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param isMultiValued |
| | | * Indicates whether this argument may be specified more than once to |
| | | * provide multiple values. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param defaultValue |
| | | * The default value that should be used for this argument if none is |
| | | * provided in a properties file or on the command line. This may be |
| | | * <CODE>null</CODE> if there is no generic default. |
| | | * @param propertyName |
| | | * The name of the property in a property file that may be used to |
| | | * override the default value but will be overridden by a |
| | | * command-line argument. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public StringArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean isMultiValued, final boolean needsValue, |
| | | final LocalizableMessage valuePlaceholder, final String defaultValue, |
| | | final String propertyName, final LocalizableMessage description) |
| | | throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, |
| | | needsValue, valuePlaceholder, defaultValue, propertyName, description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new string argument with the provided information. |
| | | * |
| | | * @param name |
| | | * The generic name that should be used to refer to this argument. |
| | | * @param shortIdentifier |
| | | * The single-character identifier for this argument, or |
| | | * <CODE>null</CODE> if there is none. |
| | | * @param longIdentifier |
| | | * The long identifier for this argument, or <CODE>null</CODE> if |
| | | * there is none. |
| | | * @param isRequired |
| | | * Indicates whether this argument must be specified on the command |
| | | * line. |
| | | * @param needsValue |
| | | * Indicates whether this argument requires a value. |
| | | * @param valuePlaceholder |
| | | * The placeholder for the argument value that will be displayed in |
| | | * usage information, or <CODE>null</CODE> if this argument does not |
| | | * require a value. |
| | | * @param description |
| | | * LocalizableMessage for the description of this argument. |
| | | * @throws ArgumentException |
| | | * If there is a problem with any of the parameters used to create |
| | | * this argument. |
| | | */ |
| | | public StringArgument(final String name, final Character shortIdentifier, |
| | | final String longIdentifier, final boolean isRequired, |
| | | final boolean needsValue, final LocalizableMessage valuePlaceholder, |
| | | final LocalizableMessage description) throws ArgumentException |
| | | { |
| | | super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, |
| | | valuePlaceholder, null, null, description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in this |
| | | * argument. |
| | | * |
| | | * @param valueString |
| | | * The value for which to make the determination. |
| | | * @param invalidReason |
| | | * A buffer into which the invalid reason may be written if the value |
| | | * is not acceptable. |
| | | * @return <CODE>true</CODE> if the value is acceptable, or <CODE>false</CODE> |
| | | * if it is not. |
| | | */ |
| | | @Override |
| | | public boolean valueIsAcceptable(final String valueString, |
| | | final LocalizableMessageBuilder invalidReason) |
| | | { |
| | | // All values will be acceptable for this argument. |
| | | return true; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a number of constants used in one or more Directory Server |
| | | * tools. |
| | | */ |
| | | final class ToolConstants |
| | | { |
| | | /** |
| | | * The name of the SASL property that can be used to provide the |
| | | * authentication ID for the bind. |
| | | */ |
| | | static final String SASL_PROPERTY_AUTHID = "authid"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the authorization |
| | | * ID for the bind. |
| | | */ |
| | | static final String SASL_PROPERTY_AUTHZID = "authzid"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the digest URI |
| | | * for the bind. |
| | | */ |
| | | static final String SASL_PROPERTY_DIGEST_URI = "digest-uri"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the KDC for use |
| | | * in Kerberos authentication. |
| | | */ |
| | | static final String SASL_PROPERTY_KDC = "kdc"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the quality of |
| | | * protection for the bind. |
| | | */ |
| | | static final String SASL_PROPERTY_QOP = "qop"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the realm for the |
| | | * bind. |
| | | */ |
| | | static final String SASL_PROPERTY_REALM = "realm"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide trace information |
| | | * for a SASL ANONYMOUS request. |
| | | */ |
| | | static final String SASL_PROPERTY_TRACE = "trace"; |
| | | |
| | | /** |
| | | * The name of the SASL property that can be used to provide the SASL |
| | | * mechanism to use. |
| | | */ |
| | | static final String SASL_PROPERTY_MECH = "mech"; |
| | | |
| | | /** |
| | | * The name of the opends configuration direction in the user home directory. |
| | | */ |
| | | static final String DEFAULT_OPENDS_CONFIG_DIR = ".opends"; |
| | | |
| | | /** |
| | | * The default properties file name. |
| | | */ |
| | | static final String DEFAULT_OPENDS_PROPERTIES_FILE_NAME = "tools"; |
| | | |
| | | /** |
| | | * The default properties file extension. |
| | | */ |
| | | static final String DEFAULT_OPENDS_PROPERTIES_FILE_EXTENSION = ".properties"; |
| | | |
| | | /** |
| | | * The value for the short option batchFilePath. |
| | | */ |
| | | static final char OPTION_SHORT_BATCH_FILE_PATH = 'F'; |
| | | |
| | | /** |
| | | * The value for the long option batchFilePath . |
| | | */ |
| | | static final String OPTION_LONG_BATCH_FILE_PATH = "batchFilePath"; |
| | | |
| | | /** |
| | | * The value for the short option hostname. |
| | | */ |
| | | static final char OPTION_SHORT_HOST = 'h'; |
| | | |
| | | /** |
| | | * The value for the long option hostname. |
| | | */ |
| | | static final String OPTION_LONG_HOST = "hostname"; |
| | | |
| | | /** |
| | | * The value for the short option port. |
| | | */ |
| | | static final char OPTION_SHORT_PORT = 'p'; |
| | | |
| | | /** |
| | | * The value for the long option port. |
| | | */ |
| | | static final String OPTION_LONG_PORT = "port"; |
| | | |
| | | /** |
| | | * The value for the short option useSSL. |
| | | */ |
| | | static final char OPTION_SHORT_USE_SSL = 'Z'; |
| | | |
| | | /** |
| | | * The value for the long option useSSL. |
| | | */ |
| | | static final String OPTION_LONG_USE_SSL = "useSSL"; |
| | | |
| | | /** |
| | | * The value for the short option baseDN. |
| | | */ |
| | | static final char OPTION_SHORT_BASEDN = 'b'; |
| | | |
| | | /** |
| | | * The value for the long option baseDN. |
| | | */ |
| | | static final String OPTION_LONG_BASEDN = "baseDN"; |
| | | |
| | | /** |
| | | * The value for the short option bindDN. |
| | | */ |
| | | static final char OPTION_SHORT_BINDDN = 'D'; |
| | | |
| | | /** |
| | | * The value for the long option bindDN. |
| | | */ |
| | | static final String OPTION_LONG_BINDDN = "bindDN"; |
| | | |
| | | /** |
| | | * The value for the short option bindPassword. |
| | | */ |
| | | static final char OPTION_SHORT_BINDPWD = 'w'; |
| | | |
| | | /** |
| | | * The value for the long option bindPassword. |
| | | */ |
| | | static final String OPTION_LONG_BINDPWD = "bindPassword"; |
| | | |
| | | /** |
| | | * The value for the short option bindPasswordFile. |
| | | */ |
| | | static final char OPTION_SHORT_BINDPWD_FILE = 'j'; |
| | | |
| | | /** |
| | | * The value for the long option bindPasswordFile. |
| | | */ |
| | | static final String OPTION_LONG_BINDPWD_FILE = "bindPasswordFile"; |
| | | |
| | | /** |
| | | * The value for the short option compress. |
| | | */ |
| | | static final char OPTION_SHORT_COMPRESS = 'c'; |
| | | |
| | | /** |
| | | * The value for the long option compress. |
| | | */ |
| | | static final String OPTION_LONG_COMPRESS = "compress"; |
| | | |
| | | /** |
| | | * The value for the short option filename. |
| | | */ |
| | | static final char OPTION_SHORT_FILENAME = 'f'; |
| | | |
| | | /** |
| | | * The value for the long option filename. |
| | | */ |
| | | static final String OPTION_LONG_FILENAME = "filename"; |
| | | |
| | | /** |
| | | * The value for the short option ldifFile. |
| | | */ |
| | | static final char OPTION_SHORT_LDIF_FILE = 'l'; |
| | | |
| | | /** |
| | | * The value for the long option ldifFile. |
| | | */ |
| | | static final String OPTION_LONG_LDIF_FILE = "ldifFile"; |
| | | |
| | | /** |
| | | * The value for the short option useStartTLS. |
| | | */ |
| | | static final char OPTION_SHORT_START_TLS = 'q'; |
| | | |
| | | /** |
| | | * The value for the long option useStartTLS. |
| | | */ |
| | | static final String OPTION_LONG_START_TLS = "useStartTLS"; |
| | | |
| | | /** |
| | | * The value for the short option randomSeed. |
| | | */ |
| | | static final char OPTION_SHORT_RANDOM_SEED = 's'; |
| | | |
| | | /** |
| | | * The value for the long option randomSeed. |
| | | */ |
| | | static final String OPTION_LONG_RANDOM_SEED = "randomSeed"; |
| | | |
| | | /** |
| | | * The value for the short option keyStorePath. |
| | | */ |
| | | static final char OPTION_SHORT_KEYSTOREPATH = 'K'; |
| | | |
| | | /** |
| | | * The value for the long option keyStorePath. |
| | | */ |
| | | static final String OPTION_LONG_KEYSTOREPATH = "keyStorePath"; |
| | | |
| | | /** |
| | | * The value for the short option trustStorePath. |
| | | */ |
| | | static final char OPTION_SHORT_TRUSTSTOREPATH = 'P'; |
| | | |
| | | /** |
| | | * The value for the long option trustStorePath. |
| | | */ |
| | | static final String OPTION_LONG_TRUSTSTOREPATH = "trustStorePath"; |
| | | |
| | | /** |
| | | * The value for the short option keyStorePassword. |
| | | */ |
| | | static final char OPTION_SHORT_KEYSTORE_PWD = 'W'; |
| | | |
| | | /** |
| | | * The value for the long option keyStorePassword. |
| | | */ |
| | | static final String OPTION_LONG_KEYSTORE_PWD = "keyStorePassword"; |
| | | |
| | | /** |
| | | * The value for the short option trustStorePassword. |
| | | */ |
| | | static final char OPTION_SHORT_TRUSTSTORE_PWD = 'T'; |
| | | |
| | | /** |
| | | * The value for the long option trustStorePassword. |
| | | */ |
| | | static final String OPTION_LONG_TRUSTSTORE_PWD = "trustStorePassword"; |
| | | |
| | | /** |
| | | * The value for the short option keyStorePasswordFile . |
| | | */ |
| | | static final char OPTION_SHORT_KEYSTORE_PWD_FILE = 'u'; |
| | | |
| | | /** |
| | | * The value for the long option keyStorePasswordFile . |
| | | */ |
| | | static final String OPTION_LONG_KEYSTORE_PWD_FILE = "keyStorePasswordFile"; |
| | | |
| | | /** |
| | | * The value for the short option keyStorePasswordFile . |
| | | */ |
| | | static final char OPTION_SHORT_TRUSTSTORE_PWD_FILE = 'U'; |
| | | |
| | | /** |
| | | * The value for the long option keyStorePasswordFile . |
| | | */ |
| | | static final String OPTION_LONG_TRUSTSTORE_PWD_FILE = "trustStorePasswordFile"; |
| | | |
| | | /** |
| | | * The value for the short option trustAll . |
| | | */ |
| | | static final char OPTION_SHORT_TRUSTALL = 'X'; |
| | | |
| | | /** |
| | | * The value for the long option trustAll . |
| | | */ |
| | | static final String OPTION_LONG_TRUSTALL = "trustAll"; |
| | | |
| | | /** |
| | | * The value for the short option certNickname . |
| | | */ |
| | | static final char OPTION_SHORT_CERT_NICKNAME = 'N'; |
| | | |
| | | /** |
| | | * The value for the long option certNickname . |
| | | */ |
| | | static final String OPTION_LONG_CERT_NICKNAME = "certNickname"; |
| | | |
| | | /** |
| | | * The value for the long option assertionFilter . |
| | | */ |
| | | static final String OPTION_LONG_ASSERTION_FILE = "assertionFilter"; |
| | | |
| | | /** |
| | | * The value for the short option dry-run. |
| | | */ |
| | | static final char OPTION_SHORT_DRYRUN = 'n'; |
| | | |
| | | /** |
| | | * The value for the long option dry-run. |
| | | */ |
| | | static final String OPTION_LONG_DRYRUN = "dry-run"; |
| | | |
| | | /** |
| | | * The value for the short option help. |
| | | */ |
| | | static final char OPTION_SHORT_HELP = 'H'; |
| | | |
| | | /** |
| | | * The value for the long option help. |
| | | */ |
| | | static final String OPTION_LONG_HELP = "help"; |
| | | |
| | | /** |
| | | * The value for the long option cli. |
| | | */ |
| | | static final String OPTION_LONG_CLI = "cli"; |
| | | |
| | | /** |
| | | * The value for the short option cli. |
| | | */ |
| | | static final char OPTION_SHORT_CLI = 'i'; |
| | | |
| | | /** |
| | | * The value for the short option proxyAs. |
| | | */ |
| | | static final char OPTION_SHORT_PROXYAUTHID = 'Y'; |
| | | |
| | | /** |
| | | * The value for the long option proxyAs. |
| | | */ |
| | | static final String OPTION_LONG_PROXYAUTHID = "proxyAs"; |
| | | |
| | | /** |
| | | * The value for the short option saslOption. |
| | | */ |
| | | static final char OPTION_SHORT_SASLOPTION = 'o'; |
| | | |
| | | /** |
| | | * The value for the long option saslOption. |
| | | */ |
| | | static final String OPTION_LONG_SASLOPTION = "saslOption"; |
| | | |
| | | /** |
| | | * The value for the short option geteffectiverights control authzid. |
| | | */ |
| | | static final char OPTION_SHORT_EFFECTIVERIGHTSUSER = 'g'; |
| | | |
| | | /** |
| | | * The value for the long option geteffectiverights control authzid. |
| | | */ |
| | | static final String OPTION_LONG_EFFECTIVERIGHTSUSER = "getEffectiveRightsAuthzid"; |
| | | |
| | | /** |
| | | * The value for the short option geteffectiveights control attributes. |
| | | */ |
| | | static final char OPTION_SHORT_EFFECTIVERIGHTSATTR = 'e'; |
| | | |
| | | /** |
| | | * The value for the long option geteffectiverights control specific attribute |
| | | * list. |
| | | */ |
| | | static final String OPTION_LONG_EFFECTIVERIGHTSATTR = "getEffectiveRightsAttribute"; |
| | | |
| | | /** |
| | | * The value for the short option protocol version attributes. |
| | | */ |
| | | static final char OPTION_SHORT_PROTOCOL_VERSION = 'V'; |
| | | |
| | | /** |
| | | * The value for the long option protocol version attribute. |
| | | */ |
| | | static final String OPTION_LONG_PROTOCOL_VERSION = "ldapVersion"; |
| | | |
| | | /** |
| | | * The value for the long option version. |
| | | */ |
| | | static final char OPTION_SHORT_PRODUCT_VERSION = 'V'; |
| | | |
| | | /** |
| | | * The value for the long option version. |
| | | */ |
| | | static final String OPTION_LONG_PRODUCT_VERSION = "version"; |
| | | |
| | | /** |
| | | * The value for the short option description attributes. |
| | | */ |
| | | static final char OPTION_SHORT_DESCRIPTION = 'd'; |
| | | |
| | | /** |
| | | * The value for the long option description attribute. |
| | | */ |
| | | static final String OPTION_LONG_DESCRIPTION = "description"; |
| | | |
| | | /** |
| | | * The value for the short option groupName attributes. |
| | | */ |
| | | static final char OPTION_SHORT_GROUPNAME = 'g'; |
| | | |
| | | /** |
| | | * The value for the long option groupName attribute. |
| | | */ |
| | | static final String OPTION_LONG_GROUPNAME = "groupName"; |
| | | |
| | | /** |
| | | * The value for the short option newGroupName attribute. |
| | | */ |
| | | static final char OPTION_SHORT_NEWGROUPNAME = 'n'; |
| | | |
| | | /** |
| | | * The value for the long option groupName attribute. |
| | | */ |
| | | static final String OPTION_LONG_NEWGROUPNAME = "newGroupName"; |
| | | |
| | | /** |
| | | * The value for the short option member-name attributes. |
| | | */ |
| | | static final char OPTION_SHORT_MEMBERNAME = 'm'; |
| | | |
| | | /** |
| | | * The value for the long member-name version attribute. |
| | | */ |
| | | static final String OPTION_LONG_MEMBERNAME = "memberName"; |
| | | |
| | | /** |
| | | * The value for the short option serverID attributes. |
| | | */ |
| | | static final String OPTION_SHORT_SERVERID = null; |
| | | |
| | | /** |
| | | * The value for the long option serverID attribute. |
| | | */ |
| | | static final String OPTION_LONG_SERVERID = "serverID"; |
| | | |
| | | /** |
| | | * The value for the short option userID attributes. |
| | | */ |
| | | static final String OPTION_SHORT_USERID = null; |
| | | |
| | | /** |
| | | * The value for the long option userID attribute. |
| | | */ |
| | | static final String OPTION_LONG_USERID = "userID"; |
| | | |
| | | /** |
| | | * The value for the short option set. |
| | | */ |
| | | static final Character OPTION_SHORT_SET = null; |
| | | |
| | | /** |
| | | * The value for the long option set. |
| | | */ |
| | | static final String OPTION_LONG_SET = "set"; |
| | | |
| | | /** |
| | | * Value for the quiet option short form. |
| | | */ |
| | | static final Character OPTION_SHORT_QUIET = 'Q'; |
| | | |
| | | /** |
| | | * Value for the quiet option long form. |
| | | */ |
| | | static final String OPTION_LONG_QUIET = "quiet"; |
| | | |
| | | /** |
| | | * Value for noninteractive session short form. |
| | | */ |
| | | static final Character OPTION_SHORT_NO_PROMPT = 'n'; |
| | | |
| | | /** |
| | | * Value for noninteractive session long form. |
| | | */ |
| | | static final String OPTION_LONG_NO_PROMPT = "no-prompt"; |
| | | |
| | | /** |
| | | * Long form of script friendly option. |
| | | */ |
| | | static final String OPTION_LONG_SCRIPT_FRIENDLY = "script-friendly"; |
| | | |
| | | /** |
| | | * Short form of script friendly option. |
| | | */ |
| | | static final Character OPTION_SHORT_SCRIPT_FRIENDLY = 's'; |
| | | |
| | | /** |
| | | * Value for verbose option short form. |
| | | */ |
| | | static final Character OPTION_SHORT_VERBOSE = 'v'; |
| | | |
| | | /** |
| | | * Value for verbose option long form. |
| | | */ |
| | | static final String OPTION_LONG_VERBOSE = "verbose"; |
| | | |
| | | /** |
| | | * The value for the long option propertiesFilePAth . |
| | | */ |
| | | static final String OPTION_LONG_PROP_FILE_PATH = "propertiesFilePath"; |
| | | |
| | | /** |
| | | * The value for the long option propertiesFilePAth . |
| | | */ |
| | | static final String OPTION_LONG_NO_PROP_FILE = "noPropertiesFile"; |
| | | |
| | | /** |
| | | * Long form of referenced host name. |
| | | */ |
| | | static final String OPTION_LONG_REFERENCED_HOST_NAME = "referencedHostName"; |
| | | |
| | | /** |
| | | * Long form of admin UID. |
| | | */ |
| | | static final String OPTION_LONG_ADMIN_UID = "adminUID"; |
| | | |
| | | /** |
| | | * Long form of report authorization ID connection option. |
| | | */ |
| | | static final String OPTION_LONG_REPORT_AUTHZ_ID = "reportAuthzID"; |
| | | |
| | | /** |
| | | * Long form of use password policy control connection option. |
| | | */ |
| | | static final String OPTION_LONG_USE_PW_POLICY_CTL = "usePasswordPolicyControl"; |
| | | |
| | | /** |
| | | * Long form of use SASL external connection option. |
| | | */ |
| | | static final String OPTION_LONG_USE_SASL_EXTERNAL = "useSASLExternal"; |
| | | |
| | | /** |
| | | * Long form of option for the command-line encoding option. |
| | | */ |
| | | static final String OPTION_LONG_ENCODING = "encoding"; |
| | | |
| | | /** |
| | | * Long form of option specifying no wrapping of the command-line. |
| | | */ |
| | | static final String OPTION_LONG_DONT_WRAP = "dontWrap"; |
| | | |
| | | /** |
| | | * The value for the long option targetDN. |
| | | */ |
| | | static final String OPTION_LONG_TARGETDN = "targetDN"; |
| | | |
| | | /** |
| | | * Long form of email notification upon completion option. |
| | | */ |
| | | static final String OPTION_LONG_COMPLETION_NOTIFICATION_EMAIL = "completionNotify"; |
| | | |
| | | /** |
| | | * Short form of email notification upon completion option. |
| | | */ |
| | | static final Character OPTION_SHORT_COMPLETION_NOTIFICATION_EMAIL = null; |
| | | |
| | | /** |
| | | * Long form of email notification upon error option. |
| | | */ |
| | | static final String OPTION_LONG_ERROR_NOTIFICATION_EMAIL = "errorNotify"; |
| | | |
| | | /** |
| | | * Short form of email notification upon error option. |
| | | */ |
| | | static final Character OPTION_SHORT_ERROR_NOTIFICATION_EMAIL = null; |
| | | |
| | | /** |
| | | * Long form of dependency option. |
| | | */ |
| | | static final String OPTION_LONG_DEPENDENCY = "dependency"; |
| | | |
| | | /** |
| | | * Short form of dependency option. |
| | | */ |
| | | static final Character OPTION_SHORT_DEPENDENCY = null; |
| | | |
| | | /** |
| | | * Long form of failed dependency action option. |
| | | */ |
| | | static final String OPTION_LONG_FAILED_DEPENDENCY_ACTION = "failedDependencyAction"; |
| | | |
| | | /** |
| | | * Short form of failed dependency action option. |
| | | */ |
| | | static final Character OPTION_SHORT_FAILED_DEPENDENCY_ACTION = null; |
| | | |
| | | /** |
| | | * The default separator to be used in tables. |
| | | */ |
| | | static final String LIST_TABLE_SEPARATOR = ":"; |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private ToolConstants() |
| | | { |
| | | |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.util.StaticUtils.EOL; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.util.StringTokenizer; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.controls.*; |
| | | import org.opends.sdk.responses.BindResult; |
| | | |
| | | import com.sun.opends.sdk.controls.AccountUsabilityRequestControl; |
| | | import com.sun.opends.sdk.tools.AuthenticatedConnectionFactory.AuthenticatedConnection; |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides utility functions for all the client side tools. |
| | | */ |
| | | final class Utils |
| | | { |
| | | /** |
| | | * The name of a command-line script used to launch a tool. |
| | | */ |
| | | static final String PROPERTY_SCRIPT_NAME = "com.sun.opends.sdk.tools.scriptName"; |
| | | |
| | | /** |
| | | * The column at which to wrap long lines of output in the command-line tools. |
| | | */ |
| | | static final int MAX_LINE_WIDTH; |
| | | |
| | | static |
| | | { |
| | | int columns = 80; |
| | | try |
| | | { |
| | | final String s = System.getenv("COLUMNS"); |
| | | if (s != null) |
| | | { |
| | | columns = Integer.parseInt(s); |
| | | } |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | // Do nothing. |
| | | } |
| | | MAX_LINE_WIDTH = columns - 1; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Filters the provided value to ensure that it is appropriate for use as an |
| | | * exit code. Exit code values are generally only allowed to be between 0 and |
| | | * 255, so any value outside of this range will be converted to 255, which is |
| | | * the typical exit code used to indicate an overflow value. |
| | | * |
| | | * @param exitCode |
| | | * The exit code value to be processed. |
| | | * @return An integer value between 0 and 255, inclusive. If the provided exit |
| | | * code was already between 0 and 255, then the original value will be |
| | | * returned. If the provided value was out of this range, then 255 |
| | | * will be returned. |
| | | */ |
| | | static int filterExitCode(final int exitCode) |
| | | { |
| | | if (exitCode < 0) |
| | | { |
| | | return 255; |
| | | } |
| | | else if (exitCode > 255) |
| | | { |
| | | return 255; |
| | | } |
| | | else |
| | | { |
| | | return exitCode; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parse the specified command line argument to create the appropriate |
| | | * LDAPControl. The argument string should be in the format |
| | | * controloid[:criticality[:value|::b64value|:<fileurl]] |
| | | * |
| | | * @param argString |
| | | * The argument string containing the encoded control information. |
| | | * @return The control decoded from the provided string, or <CODE>null</CODE> |
| | | * if an error occurs while parsing the argument value. |
| | | * @throws org.opends.sdk.DecodeException |
| | | * If an error occurs. |
| | | */ |
| | | static GenericControl getControl(final String argString) |
| | | throws DecodeException |
| | | { |
| | | String controlOID = null; |
| | | boolean controlCriticality = false; |
| | | ByteString controlValue = null; |
| | | |
| | | int idx = argString.indexOf(":"); |
| | | |
| | | if (idx < 0) |
| | | { |
| | | controlOID = argString; |
| | | } |
| | | else |
| | | { |
| | | controlOID = argString.substring(0, idx); |
| | | } |
| | | |
| | | final String lowerOID = StaticUtils.toLowerCase(controlOID); |
| | | if (lowerOID.equals("accountusable") || lowerOID.equals("accountusability")) |
| | | { |
| | | controlOID = AccountUsabilityRequestControl.OID; |
| | | } |
| | | else if (lowerOID.equals("authzid") |
| | | || lowerOID.equals("authorizationidentity")) |
| | | { |
| | | controlOID = AuthorizationIdentityRequestControl.OID; |
| | | } |
| | | else if (lowerOID.equals("noop") || lowerOID.equals("no-op")) |
| | | { |
| | | // controlOID = OID_LDAP_NOOP_OPENLDAP_ASSIGNED; |
| | | } |
| | | else if (lowerOID.equals("subentries")) |
| | | { |
| | | // controlOID = OID_LDAP_SUBENTRIES; |
| | | } |
| | | else if (lowerOID.equals("managedsait")) |
| | | { |
| | | // controlOID = OID_MANAGE_DSAIT_CONTROL; |
| | | } |
| | | else if (lowerOID.equals("pwpolicy") || lowerOID.equals("passwordpolicy")) |
| | | { |
| | | controlOID = PasswordPolicyRequestControl.OID; |
| | | } |
| | | else if (lowerOID.equals("subtreedelete") || lowerOID.equals("treedelete")) |
| | | { |
| | | controlOID = SubtreeDeleteRequestControl.OID; |
| | | } |
| | | else if (lowerOID.equals("realattrsonly") |
| | | || lowerOID.equals("realattributesonly")) |
| | | { |
| | | // controlOID = OID_REAL_ATTRS_ONLY; |
| | | } |
| | | else if (lowerOID.equals("virtualattrsonly") |
| | | || lowerOID.equals("virtualattributesonly")) |
| | | { |
| | | // controlOID = OID_VIRTUAL_ATTRS_ONLY; |
| | | } |
| | | else if (lowerOID.equals("effectiverights") |
| | | || lowerOID.equals("geteffectiverights")) |
| | | { |
| | | controlOID = GetEffectiveRightsRequestControl.OID; |
| | | } |
| | | |
| | | if (idx < 0) |
| | | { |
| | | return GenericControl.newControl(controlOID); |
| | | } |
| | | |
| | | final String remainder = argString.substring(idx + 1, argString.length()); |
| | | |
| | | idx = remainder.indexOf(":"); |
| | | if (idx == -1) |
| | | { |
| | | if (remainder.equalsIgnoreCase("true")) |
| | | { |
| | | controlCriticality = true; |
| | | } |
| | | else if (remainder.equalsIgnoreCase("false")) |
| | | { |
| | | controlCriticality = false; |
| | | } |
| | | else |
| | | { |
| | | // TODO: I18N |
| | | throw DecodeException.error(LocalizableMessage |
| | | .raw("Invalid format for criticality value:" + remainder)); |
| | | } |
| | | return GenericControl.newControl(controlOID, controlCriticality); |
| | | |
| | | } |
| | | |
| | | final String critical = remainder.substring(0, idx); |
| | | if (critical.equalsIgnoreCase("true")) |
| | | { |
| | | controlCriticality = true; |
| | | } |
| | | else if (critical.equalsIgnoreCase("false")) |
| | | { |
| | | controlCriticality = false; |
| | | } |
| | | else |
| | | { |
| | | // TODO: I18N |
| | | throw DecodeException.error(LocalizableMessage |
| | | .raw("Invalid format for criticality value:" + critical)); |
| | | } |
| | | |
| | | final String valString = remainder.substring(idx + 1, remainder.length()); |
| | | if (valString.charAt(0) == ':') |
| | | { |
| | | controlValue = ByteString.valueOf(valString.substring(1, valString |
| | | .length())); |
| | | } |
| | | else if (valString.charAt(0) == '<') |
| | | { |
| | | // Read data from the file. |
| | | final String filePath = valString.substring(1, valString.length()); |
| | | try |
| | | { |
| | | final byte[] val = readBytesFromFile(filePath); |
| | | controlValue = ByteString.wrap(val); |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | controlValue = ByteString.valueOf(valString); |
| | | } |
| | | |
| | | return GenericControl.newControl(controlOID, controlCriticality, |
| | | controlValue); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Prints a multi-line error message with the provided information to the |
| | | * given print stream. |
| | | * |
| | | * @param app |
| | | * The console app to use to write the error message. |
| | | * @param ere |
| | | * The error result. |
| | | * @return The error code. |
| | | */ |
| | | static int printErrorMessage(final ConsoleApplication app, |
| | | final ErrorResultException ere) |
| | | { |
| | | // if ((ere.getMessage() != null) && (ere.getMessage().length() > |
| | | // 0)) |
| | | // { |
| | | // app.println(LocalizableMessage.raw(ere.getMessage())); |
| | | // } |
| | | |
| | | if (ere.getResult().getResultCode().intValue() >= 0) |
| | | { |
| | | app.println(ERR_TOOL_RESULT_CODE.get(ere.getResult().getResultCode() |
| | | .intValue(), ere.getResult().getResultCode().toString())); |
| | | } |
| | | |
| | | if ((ere.getResult().getDiagnosticMessage() != null) |
| | | && (ere.getResult().getDiagnosticMessage().length() > 0)) |
| | | { |
| | | app.println(ERR_TOOL_ERROR_MESSAGE.get(ere.getResult() |
| | | .getDiagnosticMessage())); |
| | | } |
| | | |
| | | if (ere.getResult().getMatchedDN() != null |
| | | && ere.getResult().getMatchedDN().length() > 0) |
| | | { |
| | | app.println(ERR_TOOL_MATCHED_DN.get(ere.getResult().getMatchedDN())); |
| | | } |
| | | |
| | | if (app.isVerbose() && ere.getResult().getCause() != null) |
| | | { |
| | | ere.getResult().getCause().printStackTrace(app.getErrorStream()); |
| | | } |
| | | |
| | | return ere.getResult().getResultCode().intValue(); |
| | | } |
| | | |
| | | |
| | | |
| | | static void printPasswordPolicyResults(final ConsoleApplication app, |
| | | final Connection connection) |
| | | { |
| | | if (connection instanceof AuthenticatedConnection) |
| | | { |
| | | final AuthenticatedConnection conn = (AuthenticatedConnection) connection; |
| | | final BindResult result = conn.getAuthenticatedBindResult(); |
| | | |
| | | try |
| | | { |
| | | final AuthorizationIdentityResponseControl control = result.getControl( |
| | | AuthorizationIdentityResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | final LocalizableMessage message = INFO_BIND_AUTHZID_RETURNED |
| | | .get(control.getAuthorizationID()); |
| | | app.println(message); |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | app.println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final PasswordExpiredResponseControl control = result.getControl( |
| | | PasswordExpiredResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | final LocalizableMessage message = INFO_BIND_PASSWORD_EXPIRED.get(); |
| | | app.println(message); |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | app.println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final PasswordExpiringResponseControl control = result.getControl( |
| | | PasswordExpiringResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | final LocalizableMessage timeString = Utils |
| | | .secondsToTimeString(control.getSecondsUntilExpiration()); |
| | | final LocalizableMessage message = INFO_BIND_PASSWORD_EXPIRING |
| | | .get(timeString); |
| | | app.println(message); |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | app.println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final PasswordPolicyResponseControl control = result.getControl( |
| | | PasswordPolicyResponseControl.DECODER, new DecodeOptions()); |
| | | if (control != null) |
| | | { |
| | | final PasswordPolicyErrorType errorType = control.getErrorType(); |
| | | if (errorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) |
| | | { |
| | | final LocalizableMessage message = INFO_BIND_PASSWORD_EXPIRED.get(); |
| | | app.println(message); |
| | | } |
| | | else if (errorType == PasswordPolicyErrorType.ACCOUNT_LOCKED) |
| | | { |
| | | final LocalizableMessage message = INFO_BIND_ACCOUNT_LOCKED.get(); |
| | | app.println(message); |
| | | } |
| | | else if (errorType == PasswordPolicyErrorType.CHANGE_AFTER_RESET) |
| | | { |
| | | |
| | | final LocalizableMessage message = INFO_BIND_MUST_CHANGE_PASSWORD |
| | | .get(); |
| | | app.println(message); |
| | | } |
| | | |
| | | final PasswordPolicyWarningType warningType = control |
| | | .getWarningType(); |
| | | if (warningType == PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION) |
| | | { |
| | | final LocalizableMessage timeString = Utils |
| | | .secondsToTimeString(control.getWarningValue()); |
| | | final LocalizableMessage message = INFO_BIND_PASSWORD_EXPIRING |
| | | .get(timeString); |
| | | app.println(message); |
| | | } |
| | | else if (warningType == PasswordPolicyWarningType.GRACE_LOGINS_REMAINING) |
| | | { |
| | | final LocalizableMessage message = INFO_BIND_GRACE_LOGINS_REMAINING |
| | | .get(control.getWarningValue()); |
| | | app.println(message); |
| | | } |
| | | } |
| | | } |
| | | catch (final DecodeException e) |
| | | { |
| | | app.println(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Read the data from the specified file and return it in a byte array. |
| | | * |
| | | * @param filePath |
| | | * The path to the file that should be read. |
| | | * @return A byte array containing the contents of the requested file. |
| | | * @throws IOException |
| | | * If a problem occurs while trying to read the specified file. |
| | | */ |
| | | static byte[] readBytesFromFile(final String filePath) throws IOException |
| | | { |
| | | byte[] val = null; |
| | | FileInputStream fis = null; |
| | | try |
| | | { |
| | | final File file = new File(filePath); |
| | | fis = new FileInputStream(file); |
| | | final long length = file.length(); |
| | | val = new byte[(int) length]; |
| | | // Read in the bytes |
| | | int offset = 0; |
| | | int numRead = 0; |
| | | while (offset < val.length |
| | | && (numRead = fis.read(val, offset, val.length - offset)) >= 0) |
| | | { |
| | | offset += numRead; |
| | | } |
| | | |
| | | // Ensure all the bytes have been read in |
| | | if (offset < val.length) |
| | | { |
| | | throw new IOException("Could not completely read file " + filePath); |
| | | } |
| | | |
| | | return val; |
| | | } |
| | | finally |
| | | { |
| | | if (fis != null) |
| | | { |
| | | fis.close(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a user-friendly string that indicates the length of time (in |
| | | * days, hours, minutes, and seconds) in the specified number of seconds. |
| | | * |
| | | * @param numSeconds |
| | | * The number of seconds to be converted to a more user-friendly |
| | | * value. |
| | | * @return The user-friendly representation of the specified number of |
| | | * seconds. |
| | | */ |
| | | static LocalizableMessage secondsToTimeString(final int numSeconds) |
| | | { |
| | | if (numSeconds < 60) |
| | | { |
| | | // We can express it in seconds. |
| | | return INFO_TIME_IN_SECONDS.get(numSeconds); |
| | | } |
| | | else if (numSeconds < 3600) |
| | | { |
| | | // We can express it in minutes and seconds. |
| | | final int m = numSeconds / 60; |
| | | final int s = numSeconds % 60; |
| | | return INFO_TIME_IN_MINUTES_SECONDS.get(m, s); |
| | | } |
| | | else if (numSeconds < 86400) |
| | | { |
| | | // We can express it in hours, minutes, and seconds. |
| | | final int h = numSeconds / 3600; |
| | | final int m = (numSeconds % 3600) / 60; |
| | | final int s = numSeconds % 3600 % 60; |
| | | return INFO_TIME_IN_HOURS_MINUTES_SECONDS.get(h, m, s); |
| | | } |
| | | else |
| | | { |
| | | // We can express it in days, hours, minutes, and seconds. |
| | | final int d = numSeconds / 86400; |
| | | final int h = (numSeconds % 86400) / 3600; |
| | | final int m = (numSeconds % 86400 % 3600) / 60; |
| | | final int s = numSeconds % 86400 % 3600 % 60; |
| | | return INFO_TIME_IN_DAYS_HOURS_MINUTES_SECONDS.get(d, h, m, s); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Inserts line breaks into the provided buffer to wrap text at no more than |
| | | * the specified column width. Wrapping will only be done at space boundaries |
| | | * and if there are no spaces within the specified width, then wrapping will |
| | | * be performed at the first space after the specified column. |
| | | * |
| | | * @param message |
| | | * The message to be wrapped. |
| | | * @param width |
| | | * The maximum number of characters to allow on a line if there is a |
| | | * suitable breaking point. |
| | | * @return The wrapped text. |
| | | */ |
| | | static String wrapText(final LocalizableMessage message, final int width) |
| | | { |
| | | return wrapText(message.toString(), width, 0); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Inserts line breaks into the provided buffer to wrap text at no more than |
| | | * the specified column width. Wrapping will only be done at space boundaries |
| | | * and if there are no spaces within the specified width, then wrapping will |
| | | * be performed at the first space after the specified column. In addition |
| | | * each line will be indented by the specified amount. |
| | | * |
| | | * @param message |
| | | * The message to be wrapped. |
| | | * @param width |
| | | * The maximum number of characters to allow on a line if there is a |
| | | * suitable breaking point (including any indentation). |
| | | * @param indent |
| | | * The number of columns to indent each line. |
| | | * @return The wrapped text. |
| | | */ |
| | | static String wrapText(final LocalizableMessage message, final int width, |
| | | final int indent) |
| | | { |
| | | return wrapText(message.toString(), width, indent); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Inserts line breaks into the provided buffer to wrap text at no more than |
| | | * the specified column width. Wrapping will only be done at space boundaries |
| | | * and if there are no spaces within the specified width, then wrapping will |
| | | * be performed at the first space after the specified column. |
| | | * |
| | | * @param text |
| | | * The text to be wrapped. |
| | | * @param width |
| | | * The maximum number of characters to allow on a line if there is a |
| | | * suitable breaking point. |
| | | * @return The wrapped text. |
| | | */ |
| | | static String wrapText(final String text, final int width) |
| | | { |
| | | return wrapText(text, width, 0); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Inserts line breaks into the provided buffer to wrap text at no more than |
| | | * the specified column width. Wrapping will only be done at space boundaries |
| | | * and if there are no spaces within the specified width, then wrapping will |
| | | * be performed at the first space after the specified column. In addition |
| | | * each line will be indented by the specified amount. |
| | | * |
| | | * @param text |
| | | * The text to be wrapped. |
| | | * @param width |
| | | * The maximum number of characters to allow on a line if there is a |
| | | * suitable breaking point (including any indentation). |
| | | * @param indent |
| | | * The number of columns to indent each line. |
| | | * @return The wrapped text. |
| | | */ |
| | | static String wrapText(final String text, int width, final int indent) |
| | | { |
| | | // Calculate the real width and indentation padding. |
| | | width -= indent; |
| | | final StringBuilder pb = new StringBuilder(); |
| | | for (int i = 0; i < indent; i++) |
| | | { |
| | | pb.append(' '); |
| | | } |
| | | final String padding = pb.toString(); |
| | | |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | if (text != null) |
| | | { |
| | | final StringTokenizer lineTokenizer = new StringTokenizer(text, "\r\n", |
| | | true); |
| | | while (lineTokenizer.hasMoreTokens()) |
| | | { |
| | | final String line = lineTokenizer.nextToken(); |
| | | if (line.equals("\r") || line.equals("\n")) |
| | | { |
| | | // It's an end-of-line character, so append it as-is. |
| | | buffer.append(line); |
| | | } |
| | | else if (line.length() <= width) |
| | | { |
| | | // The line fits in the specified width, so append it as-is. |
| | | buffer.append(padding); |
| | | buffer.append(line); |
| | | } |
| | | else |
| | | { |
| | | // The line doesn't fit in the specified width, so it needs to |
| | | // be |
| | | // wrapped. Do so at space boundaries. |
| | | StringBuilder lineBuffer = new StringBuilder(); |
| | | StringBuilder delimBuffer = new StringBuilder(); |
| | | final StringTokenizer wordTokenizer = new StringTokenizer(line, " ", |
| | | true); |
| | | while (wordTokenizer.hasMoreTokens()) |
| | | { |
| | | final String word = wordTokenizer.nextToken(); |
| | | if (word.equals(" ")) |
| | | { |
| | | // It's a space, so add it to the delim buffer only if the |
| | | // line |
| | | // buffer is not empty. |
| | | if (lineBuffer.length() > 0) |
| | | { |
| | | delimBuffer.append(word); |
| | | } |
| | | } |
| | | else if (word.length() > width) |
| | | { |
| | | // This is a long word that can't be wrapped, so we'll |
| | | // just have |
| | | // to make do. |
| | | if (lineBuffer.length() > 0) |
| | | { |
| | | buffer.append(padding); |
| | | buffer.append(lineBuffer); |
| | | buffer.append(EOL); |
| | | lineBuffer = new StringBuilder(); |
| | | } |
| | | buffer.append(padding); |
| | | buffer.append(word); |
| | | |
| | | if (wordTokenizer.hasMoreTokens()) |
| | | { |
| | | // The next token must be a space, so remove it. If |
| | | // there are |
| | | // still more tokens after that, then append an EOL. |
| | | wordTokenizer.nextToken(); |
| | | if (wordTokenizer.hasMoreTokens()) |
| | | { |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | |
| | | if (delimBuffer.length() > 0) |
| | | { |
| | | delimBuffer = new StringBuilder(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // It's not a space, so see if we can fit it on the curent |
| | | // line. |
| | | final int newLineLength = lineBuffer.length() |
| | | + delimBuffer.length() + word.length(); |
| | | if (newLineLength < width) |
| | | { |
| | | // It does fit on the line, so add it. |
| | | lineBuffer.append(delimBuffer).append(word); |
| | | |
| | | if (delimBuffer.length() > 0) |
| | | { |
| | | delimBuffer = new StringBuilder(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // It doesn't fit on the line, so end the current line |
| | | // and start |
| | | // a new one. |
| | | buffer.append(padding); |
| | | buffer.append(lineBuffer); |
| | | buffer.append(EOL); |
| | | |
| | | lineBuffer = new StringBuilder(); |
| | | lineBuffer.append(word); |
| | | |
| | | if (delimBuffer.length() > 0) |
| | | { |
| | | delimBuffer = new StringBuilder(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // If there's anything left in the line buffer, then add it to |
| | | // the |
| | | // final buffer. |
| | | buffer.append(padding); |
| | | buffer.append(lineBuffer); |
| | | } |
| | | } |
| | | } |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private Utils() |
| | | { |
| | | // Do nothing. |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | /** |
| | | * Classes implementing the OpenDS SDK client tools. |
| | | */ |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import static org.testng.Assert.assertTrue; |
| | | |
| | | import java.net.Socket; |
| | | import java.util.Random; |
| | | |
| | | import org.glassfish.grizzly.TransportFactory; |
| | | import org.glassfish.grizzly.nio.transport.TCPNIOTransport; |
| | | import org.testng.annotations.Test; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests PerfToolTCPNIOTransportFactoryTestCase class. |
| | | */ |
| | | public class PerfToolTCPNIOTransportFactoryTestCase extends ToolsTestCase |
| | | { |
| | | /** |
| | | * Tests the transport factory. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test() |
| | | public void testGetInstance() throws Exception |
| | | { |
| | | // Create a transport. |
| | | final TransportFactory factory = new PerfToolTCPNIOTransportFactory(); |
| | | final TCPNIOTransport transport = factory.createTCPTransport(); |
| | | final Random r = new Random(); |
| | | int port = r.nextInt(10000); |
| | | if (port < 1000) |
| | | { |
| | | port += 1000; |
| | | } |
| | | transport.bind(port); |
| | | // Establish a socket connection to see if the transport factory works. |
| | | final Socket socket = new Socket("localhost", port); |
| | | // Successfully connected if there is no exception. |
| | | assertTrue(socket.isConnected()); |
| | | // Don't stop the transport because it is shared with the ldap server. |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.tools; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.OpenDSTestCase; |
| | | import org.testng.annotations.Test; |
| | | |
| | | |
| | | |
| | | /** |
| | | * An abstract class that all tools unit tests should extend. A tool represents |
| | | * the classes found directly under the package com.sun.opends.sdk.tools. |
| | | */ |
| | | |
| | | @Test(groups = { "precommit", "tools", "sdk" }, sequential = true) |
| | | public abstract class ToolsTestCase extends OpenDSTestCase |
| | | { |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.controls; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLEREQ_CONTROL_BAD_OID; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE; |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | import org.opends.sdk.DecodeException; |
| | | import org.opends.sdk.DecodeOptions; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.controls.ControlDecoder; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The Sun-defined account usability request control. The OID for this control |
| | | * is 1.3.6.1.4.1.42.2.27.9.5.8, and it does not have a value. |
| | | * |
| | | * @see AccountUsabilityResponseControl |
| | | */ |
| | | public final class AccountUsabilityRequestControl implements Control |
| | | { |
| | | /** |
| | | * The OID for the account usability request control. |
| | | */ |
| | | public static final String OID = "1.3.6.1.4.1.42.2.27.9.5.8"; |
| | | |
| | | private final boolean isCritical; |
| | | |
| | | private static final AccountUsabilityRequestControl CRITICAL_INSTANCE = |
| | | new AccountUsabilityRequestControl(true); |
| | | private static final AccountUsabilityRequestControl NONCRITICAL_INSTANCE = |
| | | new AccountUsabilityRequestControl(false); |
| | | |
| | | /** |
| | | * A decoder which can be used for decoding the account usability request |
| | | * control. |
| | | */ |
| | | public static final ControlDecoder<AccountUsabilityRequestControl> DECODER = |
| | | new ControlDecoder<AccountUsabilityRequestControl>() |
| | | { |
| | | |
| | | public AccountUsabilityRequestControl decodeControl(final Control control, |
| | | final DecodeOptions options) throws DecodeException |
| | | { |
| | | Validator.ensureNotNull(control); |
| | | |
| | | if (control instanceof AccountUsabilityRequestControl) |
| | | { |
| | | return (AccountUsabilityRequestControl) control; |
| | | } |
| | | |
| | | if (!control.getOID().equals(OID)) |
| | | { |
| | | final LocalizableMessage message = ERR_ACCTUSABLEREQ_CONTROL_BAD_OID |
| | | .get(control.getOID(), OID); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | if (control.hasValue()) |
| | | { |
| | | final LocalizableMessage message = ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE |
| | | .get(); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | return control.isCritical() ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | }; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new account usability request control having the provided |
| | | * criticality. |
| | | * |
| | | * @param isCritical |
| | | * {@code true} if it is unacceptable to perform the operation |
| | | * without applying the semantics of this control, or {@code false} |
| | | * if it can be ignored. |
| | | * @return The new control. |
| | | */ |
| | | public static AccountUsabilityRequestControl newControl( |
| | | final boolean isCritical) |
| | | { |
| | | return isCritical ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent direct instantiation. |
| | | private AccountUsabilityRequestControl(final boolean isCritical) |
| | | { |
| | | this.isCritical = isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isCritical() |
| | | { |
| | | return isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("AccountUsableRequestControl(oid="); |
| | | builder.append(getOID()); |
| | | builder.append(", criticality="); |
| | | builder.append(isCritical()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.controls; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLERES_CONTROL_BAD_OID; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLERES_DECODE_ERROR; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLERES_NO_CONTROL_VALUE; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE; |
| | | import static com.sun.opends.sdk.util.StaticUtils.byteToHex; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.asn1.ASN1; |
| | | import org.opends.sdk.asn1.ASN1Reader; |
| | | import org.opends.sdk.asn1.ASN1Writer; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.controls.ControlDecoder; |
| | | |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The Sun-defined account usability response control. The OID for this control |
| | | * is 1.3.6.1.4.1.42.2.27.9.5.8, and it has a value encoded according to the |
| | | * following BNF: |
| | | * |
| | | * <pre> |
| | | * ACCOUNT_USABLE_RESPONSE ::= CHOICE { |
| | | * is_available [0] INTEGER, -- Seconds before expiration -- |
| | | * is_not_available [1] MORE_INFO } |
| | | * |
| | | * MORE_INFO ::= SEQUENCE { |
| | | * inactive [0] BOOLEAN DEFAULT FALSE, |
| | | * reset [1] BOOLEAN DEFAULT FALSE, |
| | | * expired [2] BOOLEAN DEFAULT_FALSE, |
| | | * remaining_grace [3] INTEGER OPTIONAL, |
| | | * seconds_before_unlock [4] INTEGER OPTIONAL } |
| | | * </pre> |
| | | * |
| | | * @see AccountUsabilityRequestControl |
| | | */ |
| | | public final class AccountUsabilityResponseControl implements Control |
| | | { |
| | | /** |
| | | * The OID for the account usability response control. |
| | | */ |
| | | public static final String OID = AccountUsabilityRequestControl.OID; |
| | | |
| | | /** |
| | | * A decoder which can be used for decoding the account usability response |
| | | * control. |
| | | */ |
| | | public static final ControlDecoder<AccountUsabilityResponseControl> DECODER = |
| | | new ControlDecoder<AccountUsabilityResponseControl>() |
| | | { |
| | | |
| | | public AccountUsabilityResponseControl decodeControl(final Control control, |
| | | final DecodeOptions options) throws DecodeException |
| | | { |
| | | Validator.ensureNotNull(control); |
| | | |
| | | if (control instanceof AccountUsabilityResponseControl) |
| | | { |
| | | return (AccountUsabilityResponseControl) control; |
| | | } |
| | | |
| | | if (!control.getOID().equals(OID)) |
| | | { |
| | | final LocalizableMessage message = ERR_ACCTUSABLERES_CONTROL_BAD_OID |
| | | .get(control.getOID(), OID); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | if (!control.hasValue()) |
| | | { |
| | | // The response control must always have a value. |
| | | final LocalizableMessage message = ERR_ACCTUSABLERES_NO_CONTROL_VALUE |
| | | .get(); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final ASN1Reader reader = ASN1.getReader(control.getValue()); |
| | | switch (reader.peekType()) |
| | | { |
| | | case TYPE_SECONDS_BEFORE_EXPIRATION: |
| | | final int secondsBeforeExpiration = (int) reader.readInteger(); |
| | | return new AccountUsabilityResponseControl(control.isCritical(), |
| | | true, false, false, false, -1, false, 0, secondsBeforeExpiration); |
| | | case TYPE_MORE_INFO: |
| | | boolean isInactive = false; |
| | | boolean isReset = false; |
| | | boolean isExpired = false; |
| | | boolean isLocked = false; |
| | | int remainingGraceLogins = -1; |
| | | int secondsBeforeUnlock = 0; |
| | | |
| | | reader.readStartSequence(); |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_INACTIVE)) |
| | | { |
| | | isInactive = reader.readBoolean(); |
| | | } |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_RESET)) |
| | | { |
| | | isReset = reader.readBoolean(); |
| | | } |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_EXPIRED)) |
| | | { |
| | | isExpired = reader.readBoolean(); |
| | | } |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == TYPE_REMAINING_GRACE_LOGINS)) |
| | | { |
| | | remainingGraceLogins = (int) reader.readInteger(); |
| | | } |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == TYPE_SECONDS_BEFORE_UNLOCK)) |
| | | { |
| | | isLocked = true; |
| | | secondsBeforeUnlock = (int) reader.readInteger(); |
| | | } |
| | | reader.readEndSequence(); |
| | | |
| | | return new AccountUsabilityResponseControl(control.isCritical(), |
| | | false, isInactive, isReset, isExpired, remainingGraceLogins, |
| | | isLocked, secondsBeforeUnlock, -1); |
| | | |
| | | default: |
| | | final LocalizableMessage message = ERR_ACCTUSABLERES_UNKNOWN_VALUE_ELEMENT_TYPE |
| | | .get(byteToHex(reader.peekType())); |
| | | throw DecodeException.error(message); |
| | | } |
| | | } |
| | | catch (final IOException e) |
| | | { |
| | | StaticUtils.DEBUG_LOG.throwing( |
| | | "AccountUsabilityResponseControl.decodeControl", "decode", e); |
| | | |
| | | final LocalizableMessage message = ERR_ACCTUSABLERES_DECODE_ERROR |
| | | .get(getExceptionMessage(e)); |
| | | throw DecodeException.error(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * The BER type to use for the seconds before expiration when the account is |
| | | * available. |
| | | */ |
| | | private static final byte TYPE_SECONDS_BEFORE_EXPIRATION = (byte) 0x80; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO sequence when the account is not |
| | | * available. |
| | | */ |
| | | private static final byte TYPE_MORE_INFO = (byte) 0xA1; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO element that indicates that the |
| | | * account has been inactivated. |
| | | */ |
| | | private static final byte TYPE_INACTIVE = (byte) 0x80; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO element that indicates that the |
| | | * password has been administratively reset. |
| | | */ |
| | | private static final byte TYPE_RESET = (byte) 0x81; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO element that indicates that the |
| | | * user's password is expired. |
| | | */ |
| | | private static final byte TYPE_EXPIRED = (byte) 0x82; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO element that provides the number of |
| | | * remaining grace logins. |
| | | */ |
| | | private static final byte TYPE_REMAINING_GRACE_LOGINS = (byte) 0x83; |
| | | |
| | | /** |
| | | * The BER type to use for the MORE_INFO element that indicates that the |
| | | * password has been administratively reset. |
| | | */ |
| | | private static final byte TYPE_SECONDS_BEFORE_UNLOCK = (byte) 0x84; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new account usability response control that may be used to |
| | | * indicate that the account is not available and provide information about |
| | | * the underlying reason. |
| | | * |
| | | * @param isInactive |
| | | * Indicates whether the user's account has been inactivated by an |
| | | * administrator. |
| | | * @param isReset |
| | | * Indicates whether the user's password has been reset by an |
| | | * administrator. |
| | | * @param isExpired |
| | | * Indicates whether the user's password has expired. |
| | | * @param remainingGraceLogins |
| | | * The number of grace logins remaining. A value of {@code 0} |
| | | * indicates that there are none remaining. A value of {@code -1} |
| | | * indicates that grace login functionality is not enabled. |
| | | * @param isLocked |
| | | * Indicates whether the user's account is currently locked out. |
| | | * @param secondsBeforeUnlock |
| | | * The length of time in seconds until the account is unlocked. A |
| | | * value of {@code -1} indicates that the account will not be |
| | | * automatically unlocked and must be reset by an administrator. |
| | | * @return The new control. |
| | | */ |
| | | public static AccountUsabilityResponseControl newControl( |
| | | final boolean isInactive, final boolean isReset, final boolean isExpired, |
| | | final int remainingGraceLogins, final boolean isLocked, |
| | | final int secondsBeforeUnlock) |
| | | { |
| | | return new AccountUsabilityResponseControl(false, false, isInactive, |
| | | isReset, isExpired, remainingGraceLogins, isLocked, |
| | | secondsBeforeUnlock, -1); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new account usability response control that may be used to |
| | | * indicate that the account is available and provide the number of seconds |
| | | * until expiration. |
| | | * |
| | | * @param secondsBeforeExpiration |
| | | * The length of time in seconds until the user's password expires, |
| | | * or {@code -1} if the user's password will not expire or the |
| | | * expiration time is unknown. |
| | | * @return The new control. |
| | | */ |
| | | public static AccountUsabilityResponseControl newControl( |
| | | final int secondsBeforeExpiration) |
| | | { |
| | | return new AccountUsabilityResponseControl(false, true, false, false, |
| | | false, -1, false, 0, secondsBeforeExpiration); |
| | | } |
| | | |
| | | |
| | | |
| | | // Indicates whether the user's account is usable. |
| | | private final boolean isUsable; |
| | | |
| | | // Indicates whether the user's password is expired. |
| | | private final boolean isExpired; |
| | | |
| | | // Indicates whether the user's account is inactive. |
| | | private final boolean isInactive; |
| | | |
| | | // Indicates whether the user's account is currently locked. |
| | | private final boolean isLocked; |
| | | |
| | | // Indicates whether the user's password has been reset and must be |
| | | // changed before anything else can be done. |
| | | private final boolean isReset; |
| | | |
| | | // The number of remaining grace logins, if available. |
| | | private final int remainingGraceLogins; |
| | | |
| | | // The length of time in seconds before the user's password expires, |
| | | // if available. |
| | | private final int secondsBeforeExpiration; |
| | | |
| | | // The length of time before the user's account is unlocked, if |
| | | // available. |
| | | private final int secondsBeforeUnlock; |
| | | |
| | | private final boolean isCritical; |
| | | |
| | | |
| | | |
| | | // Prevent direct instantiation. |
| | | private AccountUsabilityResponseControl(final boolean isCritical, |
| | | final boolean isUsable, final boolean isInactive, final boolean isReset, |
| | | final boolean isExpired, final int remainingGraceLogins, |
| | | final boolean isLocked, final int secondsBeforeUnlock, |
| | | final int secondsBeforeExpiration) |
| | | { |
| | | this.isCritical = isCritical; |
| | | this.isUsable = isUsable; |
| | | this.isInactive = isInactive; |
| | | this.isReset = isReset; |
| | | this.isExpired = isExpired; |
| | | this.remainingGraceLogins = remainingGraceLogins; |
| | | this.isLocked = isLocked; |
| | | this.secondsBeforeUnlock = secondsBeforeUnlock; |
| | | this.secondsBeforeExpiration = secondsBeforeExpiration; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the number of remaining grace logins for the user. This value is |
| | | * unreliable if the user's password has not expired. |
| | | * |
| | | * @return The number of remaining grace logins for the user, or {@code -1} if |
| | | * the grace logins feature is not enabled for the user. |
| | | */ |
| | | public int getRemainingGraceLogins() |
| | | { |
| | | return remainingGraceLogins; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the length of time in seconds before the user's password expires. |
| | | * This value is unreliable if the account is not available. |
| | | * |
| | | * @return The length of time in seconds before the user's password expires, |
| | | * or {@code -1} if it is unknown or password expiration is not |
| | | * enabled for the user. |
| | | */ |
| | | public int getSecondsBeforeExpiration() |
| | | { |
| | | return secondsBeforeExpiration; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the length of time in seconds before the user's account is |
| | | * automatically unlocked. This value is unreliable is the user's account is |
| | | * not locked. |
| | | * |
| | | * @return The length of time in seconds before the user's account is |
| | | * automatically unlocked, or {@code -1} if it requires administrative |
| | | * action to unlock the account. |
| | | */ |
| | | public int getSecondsBeforeUnlock() |
| | | { |
| | | return secondsBeforeUnlock; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() |
| | | { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | try |
| | | { |
| | | if (secondsBeforeExpiration < 0) |
| | | { |
| | | writer.writeInteger(TYPE_SECONDS_BEFORE_EXPIRATION, |
| | | secondsBeforeExpiration); |
| | | } |
| | | else |
| | | { |
| | | writer.writeStartSequence(TYPE_MORE_INFO); |
| | | if (isInactive) |
| | | { |
| | | writer.writeBoolean(TYPE_INACTIVE, true); |
| | | } |
| | | |
| | | if (isReset) |
| | | { |
| | | writer.writeBoolean(TYPE_RESET, true); |
| | | } |
| | | |
| | | if (isExpired) |
| | | { |
| | | writer.writeBoolean(TYPE_EXPIRED, true); |
| | | |
| | | if (remainingGraceLogins >= 0) |
| | | { |
| | | writer.writeInteger(TYPE_REMAINING_GRACE_LOGINS, |
| | | remainingGraceLogins); |
| | | } |
| | | } |
| | | |
| | | if (isLocked) |
| | | { |
| | | writer.writeInteger(TYPE_SECONDS_BEFORE_UNLOCK, secondsBeforeUnlock); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | return buffer.toByteString(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // This should never happen unless there is a bug somewhere. |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isCritical() |
| | | { |
| | | return isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the user's password has expired. |
| | | * |
| | | * @return <CODE>true</CODE> if the user's password has expired, or |
| | | * <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isExpired() |
| | | { |
| | | return isExpired; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the user's account has been inactivated by an |
| | | * administrator. |
| | | * |
| | | * @return <CODE>true</CODE> if the user's account has been inactivated by an |
| | | * administrator, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isInactive() |
| | | { |
| | | return isInactive; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the user's account is locked for some reason. |
| | | * |
| | | * @return <CODE>true</CODE> if the user's account is locked, or |
| | | * <CODE>false</CODE> if it is not. |
| | | */ |
| | | public boolean isLocked() |
| | | { |
| | | return isLocked; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the user's password has been administratively reset |
| | | * and the user must change that password before any other operations will be |
| | | * allowed. |
| | | * |
| | | * @return <CODE>true</CODE> if the user's password has been administratively |
| | | * reset, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isReset() |
| | | { |
| | | return isReset; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the associated user account is available for use. |
| | | * |
| | | * @return <CODE>true</CODE> if the associated user account is available, or |
| | | * <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean isUsable() |
| | | { |
| | | return isUsable; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("AccountUsableResponseControl(oid="); |
| | | builder.append(getOID()); |
| | | builder.append(", criticality="); |
| | | builder.append(isCritical()); |
| | | builder.append(", isUsable="); |
| | | builder.append(isUsable); |
| | | if (isUsable) |
| | | { |
| | | builder.append(",secondsBeforeExpiration="); |
| | | builder.append(secondsBeforeExpiration); |
| | | } |
| | | else |
| | | { |
| | | builder.append(",isInactive="); |
| | | builder.append(isInactive); |
| | | builder.append(",isReset="); |
| | | builder.append(isReset); |
| | | builder.append(",isExpired="); |
| | | builder.append(isExpired); |
| | | builder.append(",remainingGraceLogins="); |
| | | builder.append(remainingGraceLogins); |
| | | builder.append(",isLocked="); |
| | | builder.append(isLocked); |
| | | builder.append(",secondsBeforeUnlock="); |
| | | builder.append(secondsBeforeUnlock); |
| | | } |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.controls; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_REAL_ATTRS_ONLY_CONTROL_BAD_OID; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_REAL_ATTRS_ONLY_INVALID_CONTROL_VALUE; |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | import org.opends.sdk.DecodeException; |
| | | import org.opends.sdk.DecodeOptions; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.controls.ControlDecoder; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The Sun-defined real attributes only request control. The OID for this |
| | | * control is 2.16.840.1.113730.3.4.17, and it does not have a value. |
| | | */ |
| | | public final class RealAttributesOnlyRequestControl implements Control |
| | | { |
| | | /** |
| | | * The OID for the real attributes only request control. |
| | | */ |
| | | public static final String OID = "2.16.840.1.113730.3.4.17"; |
| | | |
| | | private static final RealAttributesOnlyRequestControl CRITICAL_INSTANCE = |
| | | new RealAttributesOnlyRequestControl(true); |
| | | |
| | | private static final RealAttributesOnlyRequestControl NONCRITICAL_INSTANCE = |
| | | new RealAttributesOnlyRequestControl(false); |
| | | |
| | | /** |
| | | * A decoder which can be used for decoding the real attributes only request |
| | | * control. |
| | | */ |
| | | public static final ControlDecoder<RealAttributesOnlyRequestControl> DECODER = |
| | | new ControlDecoder<RealAttributesOnlyRequestControl>() |
| | | { |
| | | |
| | | public RealAttributesOnlyRequestControl decodeControl( |
| | | final Control control, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | Validator.ensureNotNull(control); |
| | | |
| | | if (control instanceof RealAttributesOnlyRequestControl) |
| | | { |
| | | return (RealAttributesOnlyRequestControl) control; |
| | | } |
| | | |
| | | if (!control.getOID().equals(OID)) |
| | | { |
| | | final LocalizableMessage message = ERR_REAL_ATTRS_ONLY_CONTROL_BAD_OID |
| | | .get(control.getOID(), OID); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | if (control.hasValue()) |
| | | { |
| | | final LocalizableMessage message = ERR_REAL_ATTRS_ONLY_INVALID_CONTROL_VALUE |
| | | .get(); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | return control.isCritical() ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | }; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new real attributes only request control having the provided |
| | | * criticality. |
| | | * |
| | | * @param isCritical |
| | | * {@code true} if it is unacceptable to perform the operation |
| | | * without applying the semantics of this control, or {@code false} |
| | | * if it can be ignored. |
| | | * @return The new control. |
| | | */ |
| | | public static RealAttributesOnlyRequestControl newControl( |
| | | final boolean isCritical) |
| | | { |
| | | return isCritical ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | private final boolean isCritical; |
| | | |
| | | |
| | | |
| | | private RealAttributesOnlyRequestControl(final boolean isCritical) |
| | | { |
| | | this.isCritical = isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isCritical() |
| | | { |
| | | return isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("RealAttributesOnlyRequestControl(oid="); |
| | | builder.append(getOID()); |
| | | builder.append(", criticality="); |
| | | builder.append(isCritical()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | package com.sun.opends.sdk.controls; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_VIRTUAL_ATTRS_ONLY_CONTROL_BAD_OID; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE; |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | import org.opends.sdk.DecodeException; |
| | | import org.opends.sdk.DecodeOptions; |
| | | import org.opends.sdk.LocalizableMessage; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.controls.ControlDecoder; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The Sun-defined virtual attributes only request control. The OID for this |
| | | * control is 2.16.840.1.113730.3.4.19, and it does not have a value. |
| | | */ |
| | | public final class VirtualAttributesOnlyRequestControl implements Control |
| | | { |
| | | /** |
| | | * The OID for the virtual attributes only request control. |
| | | */ |
| | | public static final String OID = "2.16.840.1.113730.3.4.19"; |
| | | |
| | | private static final VirtualAttributesOnlyRequestControl CRITICAL_INSTANCE = |
| | | new VirtualAttributesOnlyRequestControl(true); |
| | | |
| | | private static final VirtualAttributesOnlyRequestControl NONCRITICAL_INSTANCE = |
| | | new VirtualAttributesOnlyRequestControl(false); |
| | | |
| | | /** |
| | | * A decoder which can be used for decoding the virtual attributes only |
| | | * request control. |
| | | */ |
| | | public static final ControlDecoder<VirtualAttributesOnlyRequestControl> |
| | | DECODER = new ControlDecoder<VirtualAttributesOnlyRequestControl>() |
| | | { |
| | | |
| | | public VirtualAttributesOnlyRequestControl decodeControl( |
| | | final Control control, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | Validator.ensureNotNull(control); |
| | | |
| | | if (control instanceof VirtualAttributesOnlyRequestControl) |
| | | { |
| | | return (VirtualAttributesOnlyRequestControl) control; |
| | | } |
| | | |
| | | if (!control.getOID().equals(OID)) |
| | | { |
| | | final LocalizableMessage message = ERR_VIRTUAL_ATTRS_ONLY_CONTROL_BAD_OID |
| | | .get(control.getOID(), OID); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | if (control.hasValue()) |
| | | { |
| | | final LocalizableMessage message = ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE |
| | | .get(); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | return control.isCritical() ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | }; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new virtual attributes only request control having the provided |
| | | * criticality. |
| | | * |
| | | * @param isCritical |
| | | * {@code true} if it is unacceptable to perform the operation |
| | | * without applying the semantics of this control, or {@code false} |
| | | * if it can be ignored. |
| | | * @return The new control. |
| | | */ |
| | | public static VirtualAttributesOnlyRequestControl newControl( |
| | | final boolean isCritical) |
| | | { |
| | | return isCritical ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | private final boolean isCritical; |
| | | |
| | | |
| | | |
| | | private VirtualAttributesOnlyRequestControl(final boolean isCritical) |
| | | { |
| | | this.isCritical = isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isCritical() |
| | | { |
| | | return isCritical; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("VirtualAttributesOnlyRequestControl(oid="); |
| | | builder.append(getOID()); |
| | | builder.append(", criticality="); |
| | | builder.append(isCritical()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | /** |
| | | * Classes implementing Sun proprietary LDAP controls. |
| | | */ |
| | | package com.sun.opends.sdk.controls; |
| | | |
| | | |
| | | |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.asn1.ASN1; |
| | | import org.opends.sdk.asn1.ASN1Reader; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.requests.AbstractExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequestDecoder; |
| | | import org.opends.sdk.responses.AbstractExtendedResultDecoder; |
| | | import org.opends.sdk.responses.ExtendedResult; |
| | | import org.opends.sdk.responses.ExtendedResultDecoder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get connection ID extended request. This operation can be used to retrieve |
| | | * the client connection ID. |
| | | * |
| | | * @see GetConnectionIDExtendedResult |
| | | */ |
| | | public final class GetConnectionIDExtendedRequest |
| | | extends |
| | | AbstractExtendedRequest<GetConnectionIDExtendedRequest, GetConnectionIDExtendedResult> |
| | | { |
| | | private static final class RequestDecoder |
| | | implements |
| | | ExtendedRequestDecoder<GetConnectionIDExtendedRequest, GetConnectionIDExtendedResult> |
| | | { |
| | | |
| | | public GetConnectionIDExtendedRequest decodeExtendedRequest( |
| | | final ExtendedRequest<?> request, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | // TODO: Check the OID and that the value is not present. |
| | | final GetConnectionIDExtendedRequest newRequest = new GetConnectionIDExtendedRequest(); |
| | | for (final Control control : request.getControls()) |
| | | { |
| | | newRequest.addControl(control); |
| | | } |
| | | return newRequest; |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class ResultDecoder extends |
| | | AbstractExtendedResultDecoder<GetConnectionIDExtendedResult> |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public GetConnectionIDExtendedResult newExtendedErrorResult( |
| | | final ResultCode resultCode, final String matchedDN, |
| | | final String diagnosticMessage) |
| | | { |
| | | if (!resultCode.isExceptional()) |
| | | { |
| | | // A successful response must contain a response name and |
| | | // value. |
| | | throw new IllegalArgumentException( |
| | | "No response name and value for result code " |
| | | + resultCode.intValue()); |
| | | } |
| | | return GetConnectionIDExtendedResult.newResult(resultCode, -1) |
| | | .setMatchedDN(matchedDN).setDiagnosticMessage(diagnosticMessage); |
| | | } |
| | | |
| | | |
| | | |
| | | public GetConnectionIDExtendedResult decodeExtendedResult( |
| | | final ExtendedResult result, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | if (result instanceof GetConnectionIDExtendedResult) |
| | | { |
| | | return (GetConnectionIDExtendedResult) result; |
| | | } |
| | | else |
| | | { |
| | | final ResultCode resultCode = result.getResultCode(); |
| | | final ByteString responseValue = result.getValue(); |
| | | |
| | | if (!resultCode.isExceptional() |
| | | && ((responseValue == null) || (responseValue.length() <= 0))) |
| | | { |
| | | throw DecodeException.error(LocalizableMessage |
| | | .raw("Empty response value")); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final ASN1Reader reader = ASN1.getReader(responseValue); |
| | | final int connectionID = (int) reader.readInteger(); |
| | | final GetConnectionIDExtendedResult newResult = GetConnectionIDExtendedResult |
| | | .newResult(resultCode, connectionID).setMatchedDN( |
| | | result.getMatchedDN()).setDiagnosticMessage( |
| | | result.getDiagnosticMessage()); |
| | | |
| | | for (final Control control : result.getControls()) |
| | | { |
| | | newResult.addControl(control); |
| | | } |
| | | |
| | | return newResult; |
| | | } |
| | | catch (final IOException e) |
| | | { |
| | | throw DecodeException.error(LocalizableMessage |
| | | .raw("Error decoding response value"), e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The OID for the extended operation that can be used to get the client |
| | | * connection ID. It will be both the request and response OID. |
| | | */ |
| | | public static final String OID = "1.3.6.1.4.1.26027.1.6.2"; |
| | | |
| | | // Singleton. |
| | | private static final GetConnectionIDExtendedRequest INSTANCE = |
| | | new GetConnectionIDExtendedRequest(); |
| | | |
| | | /** |
| | | * A decoder which can be used to decode get connection ID extended operation |
| | | * requests. |
| | | */ |
| | | public static final RequestDecoder REQUEST_DECODER = new RequestDecoder(); |
| | | |
| | | // No need to expose this. |
| | | private static final ResultDecoder RESULT_DECODER = new ResultDecoder(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new get connection ID extended request. |
| | | * |
| | | * @return The new get connection ID extended request. |
| | | */ |
| | | public static GetConnectionIDExtendedRequest newRequest() |
| | | { |
| | | return INSTANCE; |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private GetConnectionIDExtendedRequest() |
| | | { |
| | | // Nothing to do. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ExtendedResultDecoder<GetConnectionIDExtendedResult> getResultDecoder() |
| | | { |
| | | return RESULT_DECODER; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ByteString getValue() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasValue() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("GetConnectionIDExtendedRequest(requestName="); |
| | | builder.append(getOID()); |
| | | builder.append(", controls="); |
| | | builder.append(getControls()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | import org.opends.sdk.ByteStringBuilder; |
| | | import org.opends.sdk.ResultCode; |
| | | import org.opends.sdk.asn1.ASN1; |
| | | import org.opends.sdk.asn1.ASN1Writer; |
| | | import org.opends.sdk.responses.AbstractExtendedResult; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | /** |
| | | * Get connection ID extended result. |
| | | * |
| | | * @see GetConnectionIDExtendedRequest |
| | | */ |
| | | public final class GetConnectionIDExtendedResult extends |
| | | AbstractExtendedResult<GetConnectionIDExtendedResult> |
| | | { |
| | | /** |
| | | * Creates a new get connection ID extended result. |
| | | * |
| | | * @param resultCode |
| | | * The result code. |
| | | * @param connectionID |
| | | * The client connection ID. |
| | | * @return The new get connection ID extended result. |
| | | * @throws NullPointerException |
| | | * If {@code resultCode} was {@code null}. |
| | | */ |
| | | public static GetConnectionIDExtendedResult newResult( |
| | | final ResultCode resultCode, final int connectionID) |
| | | throws NullPointerException |
| | | { |
| | | Validator.ensureNotNull(resultCode); |
| | | return new GetConnectionIDExtendedResult(resultCode, connectionID); |
| | | } |
| | | |
| | | |
| | | |
| | | private int connectionID; |
| | | |
| | | |
| | | |
| | | private GetConnectionIDExtendedResult(final ResultCode resultCode, |
| | | final int connectionID) |
| | | { |
| | | super(resultCode); |
| | | this.connectionID = connectionID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the client connection ID. |
| | | * |
| | | * @return The client connection ID. |
| | | */ |
| | | public int getConnectionID() |
| | | { |
| | | return connectionID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getOID() |
| | | { |
| | | return GetConnectionIDExtendedRequest.OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ByteString getValue() |
| | | { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(6); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | |
| | | try |
| | | { |
| | | writer.writeInteger(connectionID); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // This should never happen unless there is a bug somewhere. |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | |
| | | return buffer.toByteString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasValue() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the client connection ID. |
| | | * |
| | | * @param connectionID |
| | | * The client connection ID. |
| | | * @return This get connection ID result. |
| | | */ |
| | | public GetConnectionIDExtendedResult setConnectionID(final int connectionID) |
| | | { |
| | | this.connectionID = connectionID; |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("GetConnectionIDExtendedResponse(resultCode="); |
| | | builder.append(getResultCode()); |
| | | builder.append(", matchedDN="); |
| | | builder.append(getMatchedDN()); |
| | | builder.append(", diagnosticMessage="); |
| | | builder.append(getDiagnosticMessage()); |
| | | builder.append(", referrals="); |
| | | builder.append(getReferralURIs()); |
| | | builder.append(", responseName="); |
| | | builder.append(getOID()); |
| | | builder.append(", connectionID="); |
| | | builder.append(connectionID); |
| | | builder.append(", controls="); |
| | | builder.append(getControls()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_GET_SYMMETRIC_KEY_NO_VALUE; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.asn1.ASN1; |
| | | import org.opends.sdk.asn1.ASN1Reader; |
| | | import org.opends.sdk.asn1.ASN1Writer; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.requests.AbstractExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequestDecoder; |
| | | import org.opends.sdk.responses.AbstractExtendedResultDecoder; |
| | | import org.opends.sdk.responses.ExtendedResult; |
| | | import org.opends.sdk.responses.ExtendedResultDecoder; |
| | | import org.opends.sdk.responses.Responses; |
| | | |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get symmetric key extended request. |
| | | */ |
| | | public final class GetSymmetricKeyExtendedRequest extends |
| | | AbstractExtendedRequest<GetSymmetricKeyExtendedRequest, ExtendedResult> |
| | | { |
| | | private static final class RequestDecoder implements |
| | | ExtendedRequestDecoder<GetSymmetricKeyExtendedRequest, ExtendedResult> |
| | | { |
| | | |
| | | public GetSymmetricKeyExtendedRequest decodeExtendedRequest( |
| | | final ExtendedRequest<?> request, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | final ByteString requestValue = request.getValue(); |
| | | if (requestValue == null) |
| | | { |
| | | // The request must always have a value. |
| | | final LocalizableMessage message = ERR_GET_SYMMETRIC_KEY_NO_VALUE.get(); |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | String requestSymmetricKey = null; |
| | | String instanceKeyID = null; |
| | | |
| | | try |
| | | { |
| | | final ASN1Reader reader = ASN1.getReader(requestValue); |
| | | reader.readStartSequence(); |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == TYPE_SYMMETRIC_KEY_ELEMENT)) |
| | | { |
| | | requestSymmetricKey = reader.readOctetStringAsString(); |
| | | } |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == TYPE_INSTANCE_KEY_ID_ELEMENT)) |
| | | { |
| | | instanceKeyID = reader.readOctetStringAsString(); |
| | | } |
| | | reader.readEndSequence(); |
| | | |
| | | final GetSymmetricKeyExtendedRequest newRequest = new GetSymmetricKeyExtendedRequest() |
| | | .setRequestSymmetricKey(requestSymmetricKey).setInstanceKeyID( |
| | | instanceKeyID); |
| | | |
| | | for (final Control control : request.getControls()) |
| | | { |
| | | newRequest.addControl(control); |
| | | } |
| | | |
| | | return newRequest; |
| | | } |
| | | catch (final IOException ae) |
| | | { |
| | | StaticUtils.DEBUG_LOG.throwing("GetSymmetricKeyRequest.Operation", |
| | | "decodeRequest", ae); |
| | | |
| | | final LocalizableMessage message = ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION |
| | | .get(ae.getMessage()); |
| | | throw DecodeException.error(message, ae); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class ResultDecoder extends |
| | | AbstractExtendedResultDecoder<ExtendedResult> |
| | | { |
| | | |
| | | public ExtendedResult newExtendedErrorResult(final ResultCode resultCode, |
| | | final String matchedDN, final String diagnosticMessage) |
| | | { |
| | | return Responses.newGenericExtendedResult(resultCode).setMatchedDN( |
| | | matchedDN).setDiagnosticMessage(diagnosticMessage); |
| | | } |
| | | |
| | | |
| | | |
| | | public ExtendedResult decodeExtendedResult(final ExtendedResult result, |
| | | final DecodeOptions options) throws DecodeException |
| | | { |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The request OID for the get symmetric key extended operation. |
| | | */ |
| | | public static final String OID = "1.3.6.1.4.1.26027.1.6.3"; |
| | | |
| | | /** |
| | | * The BER type value for the symmetric key element of the operation value. |
| | | */ |
| | | private static final byte TYPE_SYMMETRIC_KEY_ELEMENT = (byte) 0x80; |
| | | |
| | | /** |
| | | * The BER type value for the instance key ID element of the operation value. |
| | | */ |
| | | private static final byte TYPE_INSTANCE_KEY_ID_ELEMENT = (byte) 0x81; |
| | | |
| | | /** |
| | | * A decoder which can be used to decode get symmetric key extended operation |
| | | * requests. |
| | | */ |
| | | public static final RequestDecoder REQUEST_DECODER = new RequestDecoder(); |
| | | |
| | | // No need to expose this. |
| | | private static final ResultDecoder RESULT_DECODER = new ResultDecoder(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new get symmetric key extended request. |
| | | * |
| | | * @return The new get symmetric key extended request. |
| | | */ |
| | | public static GetSymmetricKeyExtendedRequest newRequest() |
| | | { |
| | | return new GetSymmetricKeyExtendedRequest(); |
| | | } |
| | | |
| | | |
| | | |
| | | private String requestSymmetricKey = null; |
| | | |
| | | private String instanceKeyID = null; |
| | | |
| | | |
| | | |
| | | // Instantiation via factory. |
| | | private GetSymmetricKeyExtendedRequest() |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the instance key ID. |
| | | * |
| | | * @return The instance key ID. |
| | | */ |
| | | public String getInstanceKeyID() |
| | | { |
| | | return instanceKeyID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the request symmetric key. |
| | | * |
| | | * @return The request symmetric key. |
| | | */ |
| | | public String getRequestSymmetricKey() |
| | | { |
| | | return requestSymmetricKey; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ExtendedResultDecoder<ExtendedResult> getResultDecoder() |
| | | { |
| | | return RESULT_DECODER; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ByteString getValue() |
| | | { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | |
| | | try |
| | | { |
| | | writer.writeStartSequence(); |
| | | if (requestSymmetricKey != null) |
| | | { |
| | | writer |
| | | .writeOctetString(TYPE_SYMMETRIC_KEY_ELEMENT, requestSymmetricKey); |
| | | } |
| | | if (instanceKeyID != null) |
| | | { |
| | | writer.writeOctetString(TYPE_INSTANCE_KEY_ID_ELEMENT, instanceKeyID); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // This should never happen unless there is a bug somewhere. |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | |
| | | return buffer.toByteString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasValue() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the instance key ID. |
| | | * |
| | | * @param instanceKeyID |
| | | * The instance key ID. |
| | | * @return This get symmetric key request. |
| | | */ |
| | | public GetSymmetricKeyExtendedRequest setInstanceKeyID( |
| | | final String instanceKeyID) |
| | | { |
| | | this.instanceKeyID = instanceKeyID; |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the request symmetric key. |
| | | * |
| | | * @param requestSymmetricKey |
| | | * The request symmetric key. |
| | | * @return This get symmetric key request. |
| | | */ |
| | | public GetSymmetricKeyExtendedRequest setRequestSymmetricKey( |
| | | final String requestSymmetricKey) |
| | | { |
| | | this.requestSymmetricKey = requestSymmetricKey; |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("GetSymmetricKeyExtendedRequest(requestName="); |
| | | builder.append(getOID()); |
| | | builder.append(", requestSymmetricKey="); |
| | | builder.append(requestSymmetricKey); |
| | | builder.append(", instanceKeyID="); |
| | | builder.append(instanceKeyID); |
| | | builder.append(", controls="); |
| | | builder.append(getControls()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_PWPSTATE_EXTOP_DECODE_FAILURE; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE; |
| | | import static com.sun.opends.sdk.messages.Messages.ERR_PWPSTATE_EXTOP_UNKNOWN_OP_TYPE; |
| | | import static com.sun.opends.sdk.util.StaticUtils.formatAsGeneralizedTime; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.asn1.ASN1; |
| | | import org.opends.sdk.asn1.ASN1Reader; |
| | | import org.opends.sdk.asn1.ASN1Writer; |
| | | import org.opends.sdk.controls.Control; |
| | | import org.opends.sdk.requests.AbstractExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequest; |
| | | import org.opends.sdk.requests.ExtendedRequestDecoder; |
| | | import org.opends.sdk.responses.AbstractExtendedResultDecoder; |
| | | import org.opends.sdk.responses.ExtendedResult; |
| | | import org.opends.sdk.responses.ExtendedResultDecoder; |
| | | |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class implements an LDAP extended operation that can be used to query |
| | | * and update elements of the Directory Server password policy state for a given |
| | | * user. The ASN.1 definition for the value of the extended request is: <BR> |
| | | * |
| | | * <PRE> |
| | | * PasswordPolicyStateValue ::= SEQUENCE { |
| | | * targetUser LDAPDN |
| | | * operations SEQUENCE OF PasswordPolicyStateOperation OPTIONAL } |
| | | * PasswordPolicyStateOperation ::= SEQUENCE { |
| | | * opType ENUMERATED { |
| | | * getPasswordPolicyDN (0), |
| | | * getAccountDisabledState (1), |
| | | * setAccountDisabledState (2), |
| | | * clearAccountDisabledState (3), |
| | | * getAccountExpirationTime (4), |
| | | * setAccountExpirationTime (5), |
| | | * clearAccountExpirationTime (6), |
| | | * getSecondsUntilAccountExpiration (7), |
| | | * getPasswordChangedTime (8), |
| | | * setPasswordChangedTime (9), |
| | | * clearPasswordChangedTime (10), |
| | | * getPasswordExpirationWarnedTime (11), |
| | | * setPasswordExpirationWarnedTime (12), |
| | | * clearPasswordExpirationWarnedTime (13), |
| | | * getSecondsUntilPasswordExpiration (14), |
| | | * getSecondsUntilPasswordExpirationWarning (15), |
| | | * getAuthenticationFailureTimes (16), |
| | | * addAuthenticationFailureTime (17), |
| | | * setAuthenticationFailureTimes (18), |
| | | * clearAuthenticationFailureTimes (19), |
| | | * getSecondsUntilAuthenticationFailureUnlock (20), |
| | | * getRemainingAuthenticationFailureCount (21), |
| | | * getLastLoginTime (22), |
| | | * setLastLoginTime (23), |
| | | * clearLastLoginTime (24), |
| | | * getSecondsUntilIdleLockout (25), |
| | | * getPasswordResetState (26), |
| | | * setPasswordResetState (27), |
| | | * clearPasswordResetState (28), |
| | | * getSecondsUntilPasswordResetLockout (29), |
| | | * getGraceLoginUseTimes (30), |
| | | * addGraceLoginUseTime (31), |
| | | * setGraceLoginUseTimes (32), |
| | | * clearGraceLoginUseTimes (33), |
| | | * getRemainingGraceLoginCount (34), |
| | | * getPasswordChangedByRequiredTime (35), |
| | | * setPasswordChangedByRequiredTime (36), |
| | | * clearPasswordChangedByRequiredTime (37), |
| | | * getSecondsUntilRequiredChangeTime (38), |
| | | * getPasswordHistory (39), |
| | | * clearPasswordHistory (40), |
| | | * ... }, |
| | | * opValues SEQUENCE OF OCTET STRING OPTIONAL } |
| | | * </PRE> |
| | | * |
| | | * <BR> |
| | | * Both the request and response values use the same encoded form, and they both |
| | | * use the same OID of "1.3.6.1.4.1.26027.1.6.1". The response value will only |
| | | * include get* elements. If the request did not include any operations, then |
| | | * the response will include all get* elements; otherwise, the response will |
| | | * only include the get* elements that correspond to the state fields referenced |
| | | * in the request (regardless of whether that operation was included in a get*, |
| | | * set*, add*, remove*, or clear* operation). |
| | | */ |
| | | public final class PasswordPolicyStateExtendedRequest |
| | | extends |
| | | AbstractExtendedRequest<PasswordPolicyStateExtendedRequest, PasswordPolicyStateExtendedResult> |
| | | implements PasswordPolicyStateOperationContainer |
| | | { |
| | | private static final class MultiValueOperation implements |
| | | PasswordPolicyStateOperation |
| | | { |
| | | private final PasswordPolicyStateOperationType property; |
| | | |
| | | private final List<ByteString> values; |
| | | |
| | | |
| | | |
| | | private MultiValueOperation( |
| | | final PasswordPolicyStateOperationType property, final ByteString value) |
| | | { |
| | | this.property = property; |
| | | this.values = Collections.singletonList(value); |
| | | } |
| | | |
| | | |
| | | |
| | | private MultiValueOperation( |
| | | final PasswordPolicyStateOperationType property, |
| | | final List<ByteString> values) |
| | | { |
| | | this.property = property; |
| | | this.values = values; |
| | | } |
| | | |
| | | |
| | | |
| | | public PasswordPolicyStateOperationType getOperationType() |
| | | { |
| | | return property; |
| | | } |
| | | |
| | | |
| | | |
| | | public Iterable<ByteString> getValues() |
| | | { |
| | | return values; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | return property.toString() + ": " + values; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class RequestDecoder |
| | | implements |
| | | ExtendedRequestDecoder<PasswordPolicyStateExtendedRequest, PasswordPolicyStateExtendedResult> |
| | | { |
| | | |
| | | public PasswordPolicyStateExtendedRequest decodeExtendedRequest( |
| | | final ExtendedRequest<?> request, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | final ByteString requestValue = request.getValue(); |
| | | |
| | | if ((requestValue == null) || (requestValue.length() <= 0)) |
| | | { |
| | | throw DecodeException.error(ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE.get()); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final ASN1Reader reader = ASN1.getReader(requestValue); |
| | | reader.readStartSequence(); |
| | | |
| | | // Read the target user DN |
| | | final PasswordPolicyStateExtendedRequest newRequest = |
| | | new PasswordPolicyStateExtendedRequest( |
| | | reader.readOctetStringAsString()); |
| | | |
| | | decodeOperations(reader, newRequest); |
| | | reader.readEndSequence(); |
| | | |
| | | for (final Control control : request.getControls()) |
| | | { |
| | | newRequest.addControl(control); |
| | | } |
| | | |
| | | return newRequest; |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | final LocalizableMessage message = ERR_PWPSTATE_EXTOP_DECODE_FAILURE |
| | | .get(getExceptionMessage(ioe)); |
| | | throw DecodeException.error(message, ioe); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static final class ResultDecoder extends |
| | | AbstractExtendedResultDecoder<PasswordPolicyStateExtendedResult> |
| | | { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public PasswordPolicyStateExtendedResult newExtendedErrorResult( |
| | | final ResultCode resultCode, final String matchedDN, |
| | | final String diagnosticMessage) |
| | | { |
| | | if (!resultCode.isExceptional()) |
| | | { |
| | | // A successful response must contain a response name and |
| | | // value. |
| | | throw new IllegalArgumentException( |
| | | "No response name and value for result code " |
| | | + resultCode.intValue()); |
| | | } |
| | | |
| | | return new PasswordPolicyStateExtendedResult(resultCode, (String) null) |
| | | .setMatchedDN(matchedDN).setDiagnosticMessage(diagnosticMessage); |
| | | } |
| | | |
| | | |
| | | |
| | | public PasswordPolicyStateExtendedResult decodeExtendedResult( |
| | | final ExtendedResult result, final DecodeOptions options) |
| | | throws DecodeException |
| | | { |
| | | final ResultCode resultCode = result.getResultCode(); |
| | | final ByteString responseValue = result.getValue(); |
| | | |
| | | if (!resultCode.isExceptional() |
| | | && ((responseValue == null) || (responseValue.length() <= 0))) |
| | | { |
| | | throw DecodeException.error(ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE.get()); |
| | | } |
| | | |
| | | try |
| | | { |
| | | final ASN1Reader reader = ASN1.getReader(responseValue); |
| | | reader.readStartSequence(); |
| | | |
| | | // Read the target user DN |
| | | final PasswordPolicyStateExtendedResult newResult = new PasswordPolicyStateExtendedResult( |
| | | resultCode, reader.readOctetStringAsString()).setMatchedDN( |
| | | result.getMatchedDN()).setDiagnosticMessage( |
| | | result.getDiagnosticMessage()); |
| | | |
| | | decodeOperations(reader, newResult); |
| | | reader.readEndSequence(); |
| | | |
| | | for (final Control control : result.getControls()) |
| | | { |
| | | newResult.addControl(control); |
| | | } |
| | | |
| | | return newResult; |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | final LocalizableMessage message = ERR_PWPSTATE_EXTOP_DECODE_FAILURE |
| | | .get(getExceptionMessage(ioe)); |
| | | throw DecodeException.error(message, ioe); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * The OID for the password policy state extended operation (both the request |
| | | * and response types). |
| | | */ |
| | | public static final String OID = "1.3.6.1.4.1.26027.1.6.1"; |
| | | |
| | | private final String targetUser; |
| | | |
| | | private final List<PasswordPolicyStateOperation> operations = |
| | | new ArrayList<PasswordPolicyStateOperation>(); |
| | | |
| | | static final String PASSWORD_POLICY_DN_NAME = "Password Policy DN"; |
| | | |
| | | static final String ACCOUNT_DISABLED_STATE_NAME = "Account Disabled State"; |
| | | |
| | | static final String ACCOUNT_EXPIRATION_TIME_NAME = "Account Expiration Time"; |
| | | |
| | | static final String SECONDS_UNTIL_ACCOUNT_EXPIRATION_NAME = |
| | | "Seconds Until Account Expiration"; |
| | | |
| | | static final String PASSWORD_CHANGED_TIME_NAME = "Password Changed Time"; |
| | | |
| | | static final String PASSWORD_EXPIRATION_WARNED_TIME_NAME = |
| | | "Password Expiration Warned Time"; |
| | | |
| | | static final String SECONDS_UNTIL_PASSWORD_EXPIRATION_NAME = |
| | | "Seconds Until Password Expiration"; |
| | | |
| | | static final String SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING_NAME = |
| | | "Seconds Until Password Expiration Warning"; |
| | | |
| | | static final String AUTHENTICATION_FAILURE_TIMES_NAME = |
| | | "Authentication Failure Times"; |
| | | |
| | | static final String SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK_NAME = |
| | | "Seconds Until Authentication Failure Unlock"; |
| | | |
| | | static final String REMAINING_AUTHENTICATION_FAILURE_COUNT_NAME = |
| | | "Remaining Authentication Failure Count"; |
| | | |
| | | static final String LAST_LOGIN_TIME_NAME = "Last Login Time"; |
| | | |
| | | static final String SECONDS_UNTIL_IDLE_LOCKOUT_NAME = |
| | | "Seconds Until Idle Lockout"; |
| | | |
| | | static final String PASSWORD_RESET_STATE_NAME = "Password Reset State"; |
| | | |
| | | static final String SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT_NAME = |
| | | "Seconds Until Password Reset Lockout"; |
| | | |
| | | static final String GRACE_LOGIN_USE_TIMES_NAME = "Grace Login Use Times"; |
| | | |
| | | static final String REMAINING_GRACE_LOGIN_COUNT_NAME = |
| | | "Remaining Grace Login Count"; |
| | | |
| | | static final String PASSWORD_CHANGED_BY_REQUIRED_TIME_NAME = |
| | | "Password Changed By Required Time"; |
| | | |
| | | static final String SECONDS_UNTIL_REQUIRED_CHANGE_TIME_NAME = |
| | | "Seconds Until Required Change Time"; |
| | | |
| | | static final String PASSWORD_HISTORY_NAME = "Password History"; |
| | | |
| | | /** |
| | | * A decoder which can be used to decode password policy state extended |
| | | * operation requests. |
| | | */ |
| | | public static final RequestDecoder REQUEST_DECODER = new RequestDecoder(); |
| | | |
| | | // No need to expose this. |
| | | private static final ResultDecoder RESULT_DECODER = new ResultDecoder(); |
| | | |
| | | |
| | | |
| | | static ByteString encode(final String targetUser, |
| | | final List<PasswordPolicyStateOperation> operations) |
| | | { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(6); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | |
| | | try |
| | | { |
| | | writer.writeStartSequence(); |
| | | writer.writeOctetString(targetUser); |
| | | if (!operations.isEmpty()) |
| | | { |
| | | writer.writeStartSequence(); |
| | | for (final PasswordPolicyStateOperation operation : operations) |
| | | { |
| | | writer.writeStartSequence(); |
| | | writer.writeEnumerated(operation.getOperationType().ordinal()); |
| | | if (operation.getValues() != null) |
| | | { |
| | | writer.writeStartSequence(); |
| | | for (final ByteString value : operation.getValues()) |
| | | { |
| | | writer.writeOctetString(value); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | catch (final IOException ioe) |
| | | { |
| | | // This should never happen unless there is a bug somewhere. |
| | | throw new RuntimeException(ioe); |
| | | } |
| | | |
| | | return buffer.toByteString(); |
| | | } |
| | | |
| | | |
| | | |
| | | private static void decodeOperations(final ASN1Reader reader, |
| | | final PasswordPolicyStateOperationContainer container) |
| | | throws IOException, DecodeException |
| | | { |
| | | // See if we have operations |
| | | if (reader.hasNextElement()) |
| | | { |
| | | reader.readStartSequence(); |
| | | int opType; |
| | | PasswordPolicyStateOperationType type; |
| | | while (reader.hasNextElement()) |
| | | { |
| | | reader.readStartSequence(); |
| | | // Read the opType |
| | | opType = reader.readEnumerated(); |
| | | try |
| | | { |
| | | type = PasswordPolicyStateOperationType.values()[opType]; |
| | | } |
| | | catch (final IndexOutOfBoundsException iobe) |
| | | { |
| | | throw DecodeException.error(ERR_PWPSTATE_EXTOP_UNKNOWN_OP_TYPE |
| | | .get(String.valueOf(opType)), iobe); |
| | | } |
| | | |
| | | // See if we have any values |
| | | if (reader.hasNextElement()) |
| | | { |
| | | reader.readStartSequence(); |
| | | final ArrayList<ByteString> values = new ArrayList<ByteString>(); |
| | | while (reader.hasNextElement()) |
| | | { |
| | | values.add(reader.readOctetString()); |
| | | } |
| | | reader.readEndSequence(); |
| | | container.addOperation(new MultiValueOperation(type, values)); |
| | | } |
| | | else |
| | | { |
| | | container.addOperation(type); |
| | | } |
| | | reader.readEndSequence(); |
| | | } |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new password policy state extended request using the provided |
| | | * user name. |
| | | * |
| | | * @param targetUser |
| | | * The name of the user. |
| | | */ |
| | | public PasswordPolicyStateExtendedRequest(final DN targetUser) |
| | | { |
| | | Validator.ensureNotNull(targetUser); |
| | | this.targetUser = targetUser.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new password policy state extended request using the provided |
| | | * user name. |
| | | * |
| | | * @param targetUser |
| | | * The name of the user. |
| | | */ |
| | | public PasswordPolicyStateExtendedRequest(final String targetUser) |
| | | { |
| | | Validator.ensureNotNull(targetUser); |
| | | this.targetUser = targetUser; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided authentication failure time to this request. |
| | | * |
| | | * @param date |
| | | * The authentication failure time. |
| | | */ |
| | | public void addAuthenticationFailureTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.ADD_AUTHENTICATION_FAILURE_TIMES); |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.ADD_AUTHENTICATION_FAILURE_TIMES, |
| | | ByteString.valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided grace login use time to this request. |
| | | * |
| | | * @param date |
| | | * The grace login use time. |
| | | */ |
| | | public void addGraceLoginUseTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.ADD_GRACE_LOGIN_USE_TIME); |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.ADD_GRACE_LOGIN_USE_TIME, ByteString |
| | | .valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void addOperation(final PasswordPolicyStateOperation operation) |
| | | { |
| | | operations.add(operation); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the account disabled state. |
| | | */ |
| | | public void clearAccountDisabledState() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_ACCOUNT_DISABLED_STATE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the account expiration time. |
| | | */ |
| | | public void clearAccountExpirationTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_ACCOUNT_EXPIRATION_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the authentication failure times. |
| | | */ |
| | | public void clearAuthenticationFailureTimes() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_AUTHENTICATION_FAILURE_TIMES); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the grace login use times. |
| | | */ |
| | | public void clearGraceLoginUseTimes() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_GRACE_LOGIN_USE_TIMES); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the last login time. |
| | | */ |
| | | public void clearLastLoginTime() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.CLEAR_LAST_LOGIN_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the password changed by required time. |
| | | */ |
| | | public void clearPasswordChangedByRequiredTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the password changed time. |
| | | */ |
| | | public void clearPasswordChangedTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_PASSWORD_CHANGED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the password expiration warned time. |
| | | */ |
| | | public void clearPasswordExpirationWarnedTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.CLEAR_PASSWORD_EXPIRATION_WARNED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the password history. |
| | | */ |
| | | public void clearPasswordHistory() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.CLEAR_PASSWORD_HISTORY); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Clears the password reset state. |
| | | */ |
| | | public void clearPasswordResetState() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.CLEAR_PASSWORD_RESET_STATE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getOID() |
| | | { |
| | | return OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Iterable<PasswordPolicyStateOperation> getOperations() |
| | | { |
| | | return operations; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ExtendedResultDecoder<PasswordPolicyStateExtendedResult> getResultDecoder() |
| | | { |
| | | return RESULT_DECODER; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ByteString getValue() |
| | | { |
| | | return encode(targetUser, operations); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasValue() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the account disabled state. |
| | | */ |
| | | public void requestAccountDisabledState() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_ACCOUNT_DISABLED_STATE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the account expiration time. |
| | | */ |
| | | public void requestAccountExpirationTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_ACCOUNT_EXPIRATION_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the authentication failure times. |
| | | */ |
| | | public void requestAuthenticationFailureTimes() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_AUTHENTICATION_FAILURE_TIMES); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the grace login use times. |
| | | */ |
| | | public void requestGraceLoginUseTimes() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_GRACE_LOGIN_USE_TIMES); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the last login time. |
| | | */ |
| | | public void requestLastLoginTime() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_LAST_LOGIN_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password changed by required time. |
| | | */ |
| | | public void requestPasswordChangedByRequiredTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_PASSWORD_CHANGED_BY_REQUIRED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password changed time. |
| | | */ |
| | | public void requestPasswordChangedTime() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_PASSWORD_CHANGED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password expiration warned time. |
| | | */ |
| | | public void requestPasswordExpirationWarnedTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_PASSWORD_EXPIRATION_WARNED_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password history. |
| | | */ |
| | | public void requestPasswordHistory() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_PASSWORD_HISTORY); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password policy DN. |
| | | */ |
| | | public void requestPasswordPolicyDN() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_PASSWORD_POLICY_DN); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the password reset state. |
| | | */ |
| | | public void requestPasswordResetState() |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.GET_PASSWORD_RESET_STATE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the remaining authentication failure count. |
| | | */ |
| | | public void requestRemainingAuthenticationFailureCount() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_REMAINING_AUTHENTICATION_FAILURE_COUNT); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the remaining grace login count. |
| | | */ |
| | | public void requestRemainingGraceLoginCount() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_REMAINING_GRACE_LOGIN_COUNT); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until account expiration. |
| | | */ |
| | | public void requestSecondsUntilAccountExpiration() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until authentication failure unlock. |
| | | */ |
| | | public void requestSecondsUntilAuthenticationFailureUnlock() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until idle lockout. |
| | | */ |
| | | public void requestSecondsUntilIdleLockout() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_IDLE_LOCKOUT); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until password expiration. |
| | | */ |
| | | public void requestSecondsUntilPasswordExpiration() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_PASSWORD_EXPIRATION); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until password expiration warning. |
| | | */ |
| | | public void requestSecondsUntilPasswordExpirationWarning() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until password reset lockout. |
| | | */ |
| | | public void requestSecondsUntilPasswordResetLockout() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the seconds until required change time. |
| | | */ |
| | | public void requestSecondsUntilRequiredChangeTime() |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the account disabled state. |
| | | * |
| | | * @param state |
| | | * The account disabled state. |
| | | */ |
| | | public void setAccountDisabledState(final boolean state) |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_ACCOUNT_DISABLED_STATE, ByteString |
| | | .valueOf(String.valueOf(state)))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the account expiration time. |
| | | * |
| | | * @param date |
| | | * The account expiration time. |
| | | */ |
| | | public void setAccountExpirationTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.SET_ACCOUNT_EXPIRATION_TIME); |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_ACCOUNT_EXPIRATION_TIME, |
| | | ByteString.valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the authentication failure times. |
| | | * |
| | | * @param dates |
| | | * The authentication failure times. |
| | | */ |
| | | public void setAuthenticationFailureTimes(final Date... dates) |
| | | { |
| | | if (dates == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.SET_AUTHENTICATION_FAILURE_TIMES); |
| | | } |
| | | else |
| | | { |
| | | final ArrayList<ByteString> times = new ArrayList<ByteString>( |
| | | dates.length); |
| | | for (final Date date : dates) |
| | | { |
| | | times.add(ByteString.valueOf(formatAsGeneralizedTime(date))); |
| | | } |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_AUTHENTICATION_FAILURE_TIMES, |
| | | times)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the grace login use times. |
| | | * |
| | | * @param dates |
| | | * The grace login use times. |
| | | */ |
| | | public void setGraceLoginUseTimes(final Date... dates) |
| | | { |
| | | if (dates == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.SET_GRACE_LOGIN_USE_TIMES); |
| | | } |
| | | else |
| | | { |
| | | final ArrayList<ByteString> times = new ArrayList<ByteString>( |
| | | dates.length); |
| | | for (final Date date : dates) |
| | | { |
| | | times.add(ByteString.valueOf(formatAsGeneralizedTime(date))); |
| | | } |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_GRACE_LOGIN_USE_TIMES, times)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the last login time. |
| | | * |
| | | * @param date |
| | | * The last login time. |
| | | */ |
| | | public void setLastLoginTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations.add(PasswordPolicyStateOperationType.SET_LAST_LOGIN_TIME); |
| | | |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_LAST_LOGIN_TIME, ByteString |
| | | .valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the password changed by required time. |
| | | * |
| | | * @param state |
| | | * The password changed by required time. |
| | | */ |
| | | public void setPasswordChangedByRequiredTime(final boolean state) |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, |
| | | ByteString.valueOf(String.valueOf(state)))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the password changed time. |
| | | * |
| | | * @param date |
| | | * The password changed time. |
| | | */ |
| | | public void setPasswordChangedTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.SET_PASSWORD_CHANGED_TIME); |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_PASSWORD_CHANGED_TIME, |
| | | ByteString.valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the password expiration warned time. |
| | | * |
| | | * @param date |
| | | * The password expiration warned time. |
| | | */ |
| | | public void setPasswordExpirationWarnedTime(final Date date) |
| | | { |
| | | if (date == null) |
| | | { |
| | | operations |
| | | .add(PasswordPolicyStateOperationType.SET_PASSWORD_EXPIRATION_WARNED_TIME); |
| | | |
| | | } |
| | | else |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_PASSWORD_EXPIRATION_WARNED_TIME, |
| | | ByteString.valueOf(formatAsGeneralizedTime(date)))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the password reset state. |
| | | * |
| | | * @param state |
| | | * The password reset state. |
| | | */ |
| | | public void setPasswordResetState(final boolean state) |
| | | { |
| | | operations.add(new MultiValueOperation( |
| | | PasswordPolicyStateOperationType.SET_LAST_LOGIN_TIME, ByteString |
| | | .valueOf(String.valueOf(state)))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("PasswordPolicyStateExtendedRequest(requestName="); |
| | | builder.append(getOID()); |
| | | builder.append(", targetUser="); |
| | | builder.append(targetUser); |
| | | builder.append(", operations="); |
| | | builder.append(operations); |
| | | builder.append(", controls="); |
| | | builder.append(getControls()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | import org.opends.sdk.DN; |
| | | import org.opends.sdk.ResultCode; |
| | | import org.opends.sdk.responses.AbstractExtendedResult; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The password policy state extended result. |
| | | */ |
| | | public final class PasswordPolicyStateExtendedResult extends |
| | | AbstractExtendedResult<PasswordPolicyStateExtendedResult> implements |
| | | PasswordPolicyStateOperationContainer |
| | | { |
| | | private final String targetUser; |
| | | |
| | | private final List<PasswordPolicyStateOperation> operations = |
| | | new ArrayList<PasswordPolicyStateOperation>(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new password policy state extended result with the provided |
| | | * result code and target user. |
| | | * |
| | | * @param resultCode |
| | | * The result code. |
| | | * @param targetUser |
| | | * The user name. |
| | | */ |
| | | public PasswordPolicyStateExtendedResult(final ResultCode resultCode, |
| | | final DN targetUser) |
| | | { |
| | | this(resultCode, String.valueOf(targetUser)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new password policy state extended result with the provided |
| | | * result code and target user. |
| | | * |
| | | * @param resultCode |
| | | * The result code. |
| | | * @param targetUser |
| | | * The user name. |
| | | */ |
| | | public PasswordPolicyStateExtendedResult(final ResultCode resultCode, |
| | | final String targetUser) |
| | | { |
| | | super(resultCode); |
| | | this.targetUser = targetUser; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void addOperation(final PasswordPolicyStateOperation operation) |
| | | { |
| | | operations.add(operation); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getOID() |
| | | { |
| | | // No response name defined. |
| | | return PasswordPolicyStateExtendedRequest.OID; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Iterable<PasswordPolicyStateOperation> getOperations() |
| | | { |
| | | return operations; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ByteString getValue() |
| | | { |
| | | return PasswordPolicyStateExtendedRequest.encode(targetUser, operations); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasValue() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("PasswordPolicyStateExtendedResponse(resultCode="); |
| | | builder.append(getResultCode()); |
| | | builder.append(", matchedDN="); |
| | | builder.append(getMatchedDN()); |
| | | builder.append(", diagnosticMessage="); |
| | | builder.append(getDiagnosticMessage()); |
| | | builder.append(", referrals="); |
| | | builder.append(getReferralURIs()); |
| | | builder.append(", responseName="); |
| | | builder.append(getOID()); |
| | | builder.append(", targetUser="); |
| | | builder.append(targetUser); |
| | | builder.append(", operations="); |
| | | builder.append(operations); |
| | | builder.append(", controls="); |
| | | builder.append(getControls()); |
| | | builder.append(")"); |
| | | return builder.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Password policy state operation. |
| | | */ |
| | | public interface PasswordPolicyStateOperation |
| | | { |
| | | /** |
| | | * Returns the type of operation. |
| | | * |
| | | * @return The type of operation. |
| | | */ |
| | | PasswordPolicyStateOperationType getOperationType(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the operation values. |
| | | * |
| | | * @return The operation values. |
| | | */ |
| | | Iterable<ByteString> getValues(); |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Password policy state operation container. |
| | | */ |
| | | interface PasswordPolicyStateOperationContainer |
| | | { |
| | | /** |
| | | * Adds an operation to this container. |
| | | * |
| | | * @param operation |
| | | * The operation to be added. |
| | | */ |
| | | void addOperation(PasswordPolicyStateOperation operation); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns the operations in this container. |
| | | * |
| | | * @return The operations in this container. |
| | | */ |
| | | Iterable<PasswordPolicyStateOperation> getOperations(); |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.extensions; |
| | | |
| | | |
| | | |
| | | import org.opends.sdk.ByteString; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Password policy state operation type. |
| | | */ |
| | | public enum PasswordPolicyStateOperationType implements |
| | | PasswordPolicyStateOperation |
| | | { |
| | | /** |
| | | * Get password policy DN operation. |
| | | */ |
| | | GET_PASSWORD_POLICY_DN( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_POLICY_DN_NAME), |
| | | |
| | | /** |
| | | * Get account disabled state operation. |
| | | */ |
| | | GET_ACCOUNT_DISABLED_STATE( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_DISABLED_STATE_NAME), |
| | | |
| | | /** |
| | | * Set account disabled state operation. |
| | | */ |
| | | SET_ACCOUNT_DISABLED_STATE( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_DISABLED_STATE_NAME), |
| | | |
| | | /** |
| | | * Clear account disabled state operation. |
| | | */ |
| | | CLEAR_ACCOUNT_DISABLED_STATE( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_DISABLED_STATE_NAME), |
| | | |
| | | /** |
| | | * Get account expiration time operation. |
| | | */ |
| | | GET_ACCOUNT_EXPIRATION_TIME( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_EXPIRATION_TIME_NAME), |
| | | |
| | | /** |
| | | * Set account expiration time operation. |
| | | */ |
| | | SET_ACCOUNT_EXPIRATION_TIME( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_EXPIRATION_TIME_NAME), |
| | | |
| | | /** |
| | | * Clear account expiration time operation. |
| | | */ |
| | | CLEAR_ACCOUNT_EXPIRATION_TIME( |
| | | PasswordPolicyStateExtendedRequest.ACCOUNT_EXPIRATION_TIME_NAME), |
| | | |
| | | /** |
| | | * Get seconds until account expiration operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_ACCOUNT_EXPIRATION_NAME), |
| | | |
| | | /** |
| | | * Get password changed time operation. |
| | | */ |
| | | GET_PASSWORD_CHANGED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_TIME_NAME), |
| | | |
| | | /** |
| | | * Set password changed time operation. |
| | | */ |
| | | SET_PASSWORD_CHANGED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_TIME_NAME), |
| | | |
| | | /** |
| | | * Clear password changed time operation. |
| | | */ |
| | | CLEAR_PASSWORD_CHANGED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_TIME_NAME), |
| | | |
| | | /** |
| | | * Get password expiration warned time operation. |
| | | */ |
| | | GET_PASSWORD_EXPIRATION_WARNED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_EXPIRATION_WARNED_TIME_NAME), |
| | | |
| | | /** |
| | | * Set password expiration warned time operation. |
| | | */ |
| | | SET_PASSWORD_EXPIRATION_WARNED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_EXPIRATION_WARNED_TIME_NAME), |
| | | |
| | | /** |
| | | * Clear password expiration warned time operation. |
| | | */ |
| | | CLEAR_PASSWORD_EXPIRATION_WARNED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_EXPIRATION_WARNED_TIME_NAME), |
| | | |
| | | /** |
| | | * Get seconds until password expiration operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_PASSWORD_EXPIRATION( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_PASSWORD_EXPIRATION_NAME), |
| | | |
| | | /** |
| | | * Get seconds until password expiration warning operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING_NAME), |
| | | |
| | | /** |
| | | * Get authentication failure times operation. |
| | | */ |
| | | GET_AUTHENTICATION_FAILURE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.AUTHENTICATION_FAILURE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Add authentication failure times operation. |
| | | */ |
| | | ADD_AUTHENTICATION_FAILURE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.AUTHENTICATION_FAILURE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Set authentication failure times operation. |
| | | */ |
| | | SET_AUTHENTICATION_FAILURE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.AUTHENTICATION_FAILURE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Clear authentication failure times operation. |
| | | */ |
| | | CLEAR_AUTHENTICATION_FAILURE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.AUTHENTICATION_FAILURE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Get seconds until authentication failure unlock operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK_NAME), |
| | | |
| | | /** |
| | | * Get remaining authentication failure count operation. |
| | | */ |
| | | GET_REMAINING_AUTHENTICATION_FAILURE_COUNT( |
| | | PasswordPolicyStateExtendedRequest.REMAINING_AUTHENTICATION_FAILURE_COUNT_NAME), |
| | | |
| | | /** |
| | | * Get last login time operation. |
| | | */ |
| | | GET_LAST_LOGIN_TIME(PasswordPolicyStateExtendedRequest.LAST_LOGIN_TIME_NAME), |
| | | |
| | | /** |
| | | * Set last login time operation. |
| | | */ |
| | | SET_LAST_LOGIN_TIME(PasswordPolicyStateExtendedRequest.LAST_LOGIN_TIME_NAME), |
| | | |
| | | /** |
| | | * Clear last login time operation. |
| | | */ |
| | | CLEAR_LAST_LOGIN_TIME(PasswordPolicyStateExtendedRequest.LAST_LOGIN_TIME_NAME), |
| | | |
| | | /** |
| | | * Get seconds until idle lockout operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_IDLE_LOCKOUT( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_IDLE_LOCKOUT_NAME), |
| | | |
| | | /** |
| | | * Get password reset state operation. |
| | | */ |
| | | GET_PASSWORD_RESET_STATE( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_RESET_STATE_NAME), |
| | | |
| | | /** |
| | | * Set password reset state operation. |
| | | */ |
| | | SET_PASSWORD_RESET_STATE( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_RESET_STATE_NAME), |
| | | |
| | | /** |
| | | * Clear password reset state operation. |
| | | */ |
| | | CLEAR_PASSWORD_RESET_STATE( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_RESET_STATE_NAME), |
| | | |
| | | /** |
| | | * Get seconds until password reset lockout operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT_NAME), |
| | | |
| | | /** |
| | | * Get grace login use times operation. |
| | | */ |
| | | GET_GRACE_LOGIN_USE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.GRACE_LOGIN_USE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Add grace login use times operation. |
| | | */ |
| | | ADD_GRACE_LOGIN_USE_TIME( |
| | | PasswordPolicyStateExtendedRequest.GRACE_LOGIN_USE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Set grace login use times operation. |
| | | */ |
| | | SET_GRACE_LOGIN_USE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.GRACE_LOGIN_USE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Clear grace login use times operation. |
| | | */ |
| | | CLEAR_GRACE_LOGIN_USE_TIMES( |
| | | PasswordPolicyStateExtendedRequest.GRACE_LOGIN_USE_TIMES_NAME), |
| | | |
| | | /** |
| | | * Get remaining grace login count operation. |
| | | */ |
| | | GET_REMAINING_GRACE_LOGIN_COUNT( |
| | | PasswordPolicyStateExtendedRequest.REMAINING_GRACE_LOGIN_COUNT_NAME), |
| | | |
| | | /** |
| | | * Get password changed by required time operation. |
| | | */ |
| | | GET_PASSWORD_CHANGED_BY_REQUIRED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_BY_REQUIRED_TIME_NAME), |
| | | |
| | | /** |
| | | * Set password changed by required time operation. |
| | | */ |
| | | SET_PASSWORD_CHANGED_BY_REQUIRED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_BY_REQUIRED_TIME_NAME), |
| | | |
| | | /** |
| | | * Clear password changed by required time operation. |
| | | */ |
| | | CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_CHANGED_BY_REQUIRED_TIME_NAME), |
| | | |
| | | /** |
| | | * Get seconds until required change time operation. |
| | | */ |
| | | GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME( |
| | | PasswordPolicyStateExtendedRequest.SECONDS_UNTIL_REQUIRED_CHANGE_TIME_NAME), |
| | | |
| | | /** |
| | | * Get password history operation. |
| | | */ |
| | | GET_PASSWORD_HISTORY(PasswordPolicyStateExtendedRequest.PASSWORD_HISTORY_NAME), |
| | | |
| | | /** |
| | | * Clear password history operation. |
| | | */ |
| | | CLEAR_PASSWORD_HISTORY( |
| | | PasswordPolicyStateExtendedRequest.PASSWORD_HISTORY_NAME); |
| | | |
| | | private String propertyName; |
| | | |
| | | |
| | | |
| | | private PasswordPolicyStateOperationType(final String propertyName) |
| | | { |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public PasswordPolicyStateOperationType getOperationType() |
| | | { |
| | | return this; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Iterable<ByteString> getValues() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | return propertyName; |
| | | } |
| | | } |
| opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/ASN1BufferReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/ASN1BufferWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/AbstractLDAPFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/AbstractLDAPMessageHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/InternalConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPClientFilter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPCompareFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConstants.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPDefaultTCPNIOTransport.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPListenerImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPMessageHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPServerFilter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPUtils.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLFilter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/TimeoutChecker.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnexpectedRequestException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnexpectedResponseException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnsupportedMessageException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/ASCIICharProp.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/AsynchronousFutureResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Base64.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/ByteSequenceOutputStream.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Collections2.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/CompletedFutureResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Function.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Functions.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/FutureResultTransformer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Iterables.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Iterators.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/LocalizableMessageDescriptor.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Predicate.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/RecursiveFutureResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/SizeLimitInputStream.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/StaticUtils.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/StringPrepProfile.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/SubstringReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Validator.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AVA.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractAsynchronousConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractAttribute.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractEntry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractFilterVisitor.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractMapEntry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Assertion.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AssertionFailureException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AsynchronousConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Attribute.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AttributeDescription.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AttributeFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Attributes.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthenticatedConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthenticationException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthorizationException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteSequence.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteSequenceReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteString.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteStringBuilder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/CancelledResultException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConditionResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Connection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionEventListener.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionPool.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionSecurityLayer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Connections.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConstraintViolationException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DN.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DecodeException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DecodeOptions.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DereferenceAliasesPolicy.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Entries.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Entry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/EntryFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/EntryNotFoundException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultIOException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Filter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FilterVisitor.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FutureResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/HeartBeatConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/IntermediateResponseHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/InternalConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/KeyManagers.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPClientContext.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPListener.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPListenerOptions.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPOptions.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPUrl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LinkedAttribute.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LinkedHashMapEntry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancingAlgorithm.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableMessage.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableMessageBuilder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizedIllegalArgumentException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Matcher.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Modification.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ModificationType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/MultipleEntriesFoundException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RDN.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ReferralException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RequestHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ResultCode.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ResultHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RootDSE.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SSLContextBuilder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SchemaResolver.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchResultHandler.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchResultReferenceIOException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchScope.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ServerConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ServerConnectionFactory.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SortKey.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SynchronousConnection.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TimeoutResultException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TreeMapEntry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TrustManagers.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1ByteSequenceReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Constants.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1InputStreamReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1OutputStreamWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Reader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Writer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Reader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Writer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AssertionRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/Control.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ControlDecoder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/GenericControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/GetEffectiveRightsRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ManageDsaITRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/MatchedValuesRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiredResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiringResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyErrorType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyWarningType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PermissiveModifyRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchChangeType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV1RequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV2RequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SimplePagedResultsControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SubentriesRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SubtreeDeleteRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewRequestControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewResponseControl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFStream.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecord.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitor.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitorWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionChangeRecordWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryReader.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryWriter.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractSASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableSASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClient.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClientImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequestDecoder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/Request.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/Requests.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindClientImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAbandonRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAddRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAnonymousSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCancelExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCompareRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDeleteRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableExternalSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGSSAPISASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyDNRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePlainSASLBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSearchRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSimpleBindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableStartTLSExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableUnbindRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableWhoAmIExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequestImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResultDecoder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractIntermediateResponse.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResponseImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableIntermediateResponseImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResponseImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResultDecoder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponse.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponseImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/IntermediateResponse.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Response.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Responses.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Result.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntry.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntryImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReference.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReferenceImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableBindResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableCompareResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericIntermediateResponseImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiablePasswordModifyExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultEntryImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultReferenceImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableWhoAmIExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResult.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResultImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeTypeSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeUsage.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordExactEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BinarySyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateListSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificatePairSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ConflictingSchemaElementException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchema.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchemaImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CountryStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRule.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRuleSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRule.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRuleSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DeliveryMethodSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnhancedGuideSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumOrderingMatchingRule.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EqualLengthApproximateMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/FacsimileNumberSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/FaxSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GenerateCoreSchema.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GuideSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IA5StringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/JPEGSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/KeywordEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/LDAPSyntaxDescriptionSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRule.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUse.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUseSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameAndOptionalUIDSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameForm.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameFormSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OIDSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClass.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassType.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OtherMailboxSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PostalAddressSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PrintableStringSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/RegexSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/Schema.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaBuilder.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaCompatOptions.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaConstants.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaElement.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaUtils.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SubstringAssertionSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SupportedAlgorithmSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/Syntax.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSubstringMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TeletexTerminalIdentifierSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelexNumberSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UTCTimeSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDOrderingMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UniqueMemberEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UnknownSchemaElementException.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordExactEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordSyntaxImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/WordEqualityMatchingRuleImpl.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/package-info.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/javadoc/overview.html
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_de.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_es.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_fr.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_ja.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_ko.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_zh_CN.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_zh_TW.properties
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/controls/AccountUsabilityRequestControlTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/controls/AccountUsabilityResponseControlTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/LDAPDefaultTCPNIOTransportTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/LDAPTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/messages/MessagesTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/ASCIICharPropTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/Base64TestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/StaticUtilsTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/StringPrepProfileTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/UtilTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/AttributeDescriptionTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteSequenceTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteStringBuilderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteStringTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ConnectionFactoryTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/DNTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/EntriesTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/EntryTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/FilterTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPListenerTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPServer.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPUrlTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LinkedAttributeTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/OpenDSTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/RDNTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SdkTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SuiteRunner.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SynchronousConnectionTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TestCaseUtils.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TestListener.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TypesTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ByteSequenceReaderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1InputStreamReaderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1OutputStreamWriterTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ReaderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1WriterTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/controls/ControlsTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryReaderTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryWriterTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AbandonRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AddRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AnonymousSASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/BindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/CompareRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/DeleteRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/DigestMD5SASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ExtendedRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ExternalSASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/GSSAPISASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/GenericBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyDNRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/PlainSASLBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestsTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/SimpleBindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/UnbindRequestTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/responses/ResponsesTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AbstractSchemaElementTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/ApproximateMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CoreSchemaTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/DITContentRuleSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/EnumSyntaxTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/GuideSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/IA5StringSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/LDAPSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/OrderingMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/OtherMailboxSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/RegexSyntaxTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaUtilsTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstringMatchingRuleTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SyntaxTestCase.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/TelexSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/UTCTimeSyntaxTest.java
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/UUIDSyntaxTest.java |