mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
12.00.2011 35d34914ab45c13fd073b3fe3a4795a7c2c30320
Copy source files from trunk sdk keeping revision history
596 files added
172163 ■■■■■ changed files
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ApplicationKeyManager.java 335 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Argument.java 789 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentException.java 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentGroup.java 208 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentParser.java 1919 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthRate.java 774 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java 473 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/BooleanArgument.java 126 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/CLIException.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConnectionFactoryProvider.java 911 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConsoleApplication.java 586 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/DataSource.java 589 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/FileBasedArgument.java 278 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/IntegerArgument.java 536 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPCompare.java 660 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPModify.java 798 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPPasswordModify.java 497 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPSearch.java 1298 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ModRate.java 429 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/MultiChoiceArgument.java 271 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/MultiColumnPrinter.java 547 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerformanceRunner.java 1283 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PromptingTrustManager.java 482 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/SearchRate.java 525 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/StringArgument.java 147 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ToolConstants.java 619 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Utils.java 733 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/test/java/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactoryTestCase.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/test/java/com/sun/opends/sdk/tools/ToolsTestCase.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/AccountUsabilityRequestControl.java 191 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/AccountUsabilityResponseControl.java 570 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/RealAttributesOnlyRequestControl.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/VirtualAttributesOnlyRequestControl.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetConnectionIDExtendedRequest.java 249 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetConnectionIDExtendedResult.java 183 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetSymmetricKeyExtendedRequest.java 335 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateExtendedRequest.java 1140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateExtendedResult.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperation.java 56 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperationContainer.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperationType.java 323 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/ASN1BufferReader.java 821 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/ASN1BufferWriter.java 741 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/AbstractLDAPFutureResultImpl.java 174 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/AbstractLDAPMessageHandler.java 236 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/InternalConnection.java 361 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPClientFilter.java 644 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPCompareFutureResultImpl.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConnection.java 1033 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java 352 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPConstants.java 332 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPDefaultTCPNIOTransport.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java 113 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPListenerImpl.java 182 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPMessageHandler.java 159 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPReader.java 1817 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPServerFilter.java 1163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPUtils.java 727 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/LDAPWriter.java 677 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/SASLFilter.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/TimeoutChecker.java 157 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnexpectedRequestException.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnexpectedResponseException.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/UnsupportedMessageException.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/ldap/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/ASCIICharProp.java 397 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java 508 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/AsynchronousFutureResult.java 483 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Base64.java 383 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/ByteSequenceOutputStream.java 144 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Collections2.java 507 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/CompletedFutureResult.java 196 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Function.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Functions.java 395 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/FutureResultTransformer.java 243 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Iterables.java 393 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Iterators.java 547 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/LocalizableMessageDescriptor.java 1091 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Predicate.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/RecursiveFutureResult.java 274 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/SizeLimitInputStream.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/StaticUtils.java 2271 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/StringPrepProfile.java 587 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/SubstringReader.java 184 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/Validator.java 213 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/util/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AVA.java 977 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractAsynchronousConnection.java 430 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractAttribute.java 497 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnection.java 494 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractConnectionFactory.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractEntry.java 387 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractFilterVisitor.java 220 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractLoadBalancingAlgorithm.java 446 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AbstractMapEntry.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Assertion.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AssertionFailureException.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AsynchronousConnection.java 850 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Attribute.java 484 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AttributeDescription.java 1478 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AttributeFactory.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Attributes.java 627 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthenticatedConnectionFactory.java 240 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthenticationException.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/AuthorizationException.java 62 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteSequence.java 326 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteSequenceReader.java 505 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteString.java 717 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ByteStringBuilder.java 1118 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/CancelledResultException.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConditionResult.java 298 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Connection.java 1260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionEventListener.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionException.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionFactory.java 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionPool.java 881 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConnectionSecurityLayer.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Connections.java 342 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ConstraintViolationException.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DN.java 813 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DecodeException.java 150 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DecodeOptions.java 241 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/DereferenceAliasesPolicy.java 218 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Entries.java 515 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Entry.java 550 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/EntryFactory.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/EntryNotFoundException.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultException.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ErrorResultIOException.java 76 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FailoverLoadBalancingAlgorithm.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Filter.java 2123 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FilterVisitor.java 234 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/FutureResult.java 139 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/HeartBeatConnectionFactory.java 405 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/IntermediateResponseHandler.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/InternalConnectionFactory.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/KeyManagers.java 398 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPClientContext.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPConnectionFactory.java 244 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPListener.java 383 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPListenerOptions.java 229 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPOptions.java 350 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LDAPUrl.java 978 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LinkedAttribute.java 1045 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LinkedHashMapEntry.java 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancer.java 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LoadBalancingAlgorithm.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableException.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableMessage.java 527 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizableMessageBuilder.java 435 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/LocalizedIllegalArgumentException.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Matcher.java 845 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/Modification.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ModificationType.java 208 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/MultipleEntriesFoundException.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RDN.java 420 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ReferralException.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RequestHandler.java 245 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ResultCode.java 747 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ResultHandler.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RootDSE.java 510 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java 178 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SSLContextBuilder.java 255 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SchemaResolver.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchResultHandler.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchResultReferenceIOException.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SearchScope.java 205 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ServerConnection.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ServerConnectionFactory.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SortKey.java 704 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/SynchronousConnection.java 388 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TimeoutResultException.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TreeMapEntry.java 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/TrustManagers.java 551 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1.java 226 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1ByteSequenceReader.java 562 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Constants.java 169 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1InputStreamReader.java 786 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1OutputStreamWriter.java 562 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Reader.java 431 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/ASN1Writer.java 391 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Reader.java 210 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/AbstractASN1Writer.java 156 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/asn1/package-info.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AssertionRequestControl.java 242 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityRequestControl.java 199 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/AuthorizationIdentityResponseControl.java 226 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/Control.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ControlDecoder.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java 399 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/GenericControl.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/GetEffectiveRightsRequestControl.java 427 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ManageDsaITRequestControl.java 194 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/MatchedValuesRequestControl.java 463 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiredResponseControl.java 194 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordExpiringResponseControl.java 229 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyErrorType.java 129 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyRequestControl.java 195 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyResponseControl.java 418 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PasswordPolicyWarningType.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PermissiveModifyRequestControl.java 201 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchChangeType.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PersistentSearchRequestControl.java 414 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadRequestControl.java 354 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PostReadResponseControl.java 259 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadRequestControl.java 354 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/PreReadResponseControl.java 260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV1RequestControl.java 294 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ProxiedAuthV2RequestControl.java 283 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortRequestControl.java 393 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/ServerSideSortResponseControl.java 376 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SimplePagedResultsControl.java 344 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SubentriesRequestControl.java 195 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/SubtreeDeleteRequestControl.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewRequestControl.java 525 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/VirtualListViewResponseControl.java 338 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/controls/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFReader.java 891 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFStream.java 172 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/AbstractLDIFWriter.java 544 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecord.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordReader.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitor.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordVisitorWriter.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ChangeRecordWriter.java 183 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionChangeRecordWriter.java 322 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryReader.java 429 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/ConnectionEntryWriter.java 158 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryReader.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/EntryWriter.java 104 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordReader.java 751 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFChangeRecordWriter.java 471 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryReader.java 468 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/LDIFEntryWriter.java 362 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/ldif/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/package-info.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequest.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbandonRequestImpl.java 115 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractBindRequest.java 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractExtendedRequest.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractRequestImpl.java 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractSASLBindRequest.java 74 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableBindRequest.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableExtendedRequest.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableRequest.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AbstractUnmodifiableSASLBindRequest.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequest.java 243 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AddRequestImpl.java 371 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequest.java 155 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/AnonymousSASLBindRequestImpl.java 147 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClient.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindClientImpl.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/BindRequest.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequest.java 201 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java 287 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequest.java 143 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CancelExtendedRequestImpl.java 249 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequest.java 222 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/CompareRequestImpl.java 251 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequest.java 131 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DeleteRequestImpl.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequest.java 546 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java 656 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequest.java 120 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExtendedRequestDecoder.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java 214 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequest.java 517 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GSSAPISASLBindRequestImpl.java 784 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericBindRequestImpl.java 211 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequest.java 147 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/GenericExtendedRequestImpl.java 256 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequest.java 263 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyDNRequestImpl.java 267 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequest.java 185 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/ModifyRequestImpl.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequest.java 276 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PasswordModifyExtendedRequestImpl.java 435 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequest.java 229 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/PlainSASLBindRequestImpl.java 275 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/Request.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/Requests.java 1710 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindClientImpl.java 275 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SASLBindRequest.java 108 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequest.java 356 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SearchRequestImpl.java 371 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequest.java 181 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/SimpleBindRequestImpl.java 187 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequest.java 202 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java 280 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequest.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnbindRequestImpl.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAbandonRequestImpl.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAddRequestImpl.java 201 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableAnonymousSASLBindRequestImpl.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCancelExtendedRequestImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableCompareRequestImpl.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDeleteRequestImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java 165 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableExternalSASLBindRequestImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGSSAPISASLBindRequestImpl.java 175 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericBindRequestImpl.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableGenericExtendedRequestImpl.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyDNRequestImpl.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableModifyRequestImpl.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java 88 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiablePlainSASLBindRequestImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSearchRequestImpl.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableSimpleBindRequestImpl.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableStartTLSExtendedRequestImpl.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableUnbindRequestImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/UnmodifiableWhoAmIExtendedRequestImpl.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequest.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/WhoAmIExtendedRequestImpl.java 209 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/requests/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResult.java 143 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractExtendedResultDecoder.java 137 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractIntermediateResponse.java 129 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResponseImpl.java 144 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractResultImpl.java 246 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableExtendedResultImpl.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableIntermediateResponseImpl.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResponseImpl.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/AbstractUnmodifiableResultImpl.java 149 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResult.java 215 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/BindResultImpl.java 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResult.java 174 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/CompareResultImpl.java 115 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResult.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ExtendedResultDecoder.java 134 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResult.java 212 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericExtendedResultImpl.java 169 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponse.java 123 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/GenericIntermediateResponseImpl.java 170 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/IntermediateResponse.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResult.java 230 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/PasswordModifyExtendedResultImpl.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Response.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Responses.java 665 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/Result.java 239 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/ResultImpl.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntry.java 240 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultEntryImpl.java 360 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReference.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/SearchResultReferenceImpl.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableBindResultImpl.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableCompareResultImpl.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericExtendedResultImpl.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableGenericIntermediateResponseImpl.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiablePasswordModifyExtendedResultImpl.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableResultImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultEntryImpl.java 196 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableSearchResultReferenceImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/UnmodifiableWhoAmIExtendedResultImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResult.java 223 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/WhoAmIExtendedResultImpl.java 170 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/responses/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractMatchingRuleImpl.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractOrderingMatchingRuleImpl.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSubstringMatchingRuleImpl.java 539 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AbstractSyntaxImpl.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeType.java 900 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeTypeSyntaxImpl.java 280 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AttributeUsage.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordExactEqualityMatchingRuleImpl.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/AuthPasswordSyntaxImpl.java 340 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BinarySyntaxImpl.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleImpl.java 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BitStringSyntaxImpl.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/BooleanSyntaxImpl.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleImpl.java 82 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleImpl.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleImpl.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleImpl.java 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleImpl.java 82 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListEqualityMatchingRuleImpl.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreListSubstringMatchingRuleImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleImpl.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateListSyntaxImpl.java 107 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificatePairSyntaxImpl.java 106 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CertificateSyntaxImpl.java 106 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ConflictingSchemaElementException.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchema.java 2675 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CoreSchemaImpl.java 1090 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/CountryStringSyntaxImpl.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRule.java 616 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITContentRuleSyntaxImpl.java 204 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRule.java 344 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DITStructureRuleSyntaxImpl.java 206 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DeliveryMethodSyntaxImpl.java 169 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DirectoryStringSyntaxImpl.java 126 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java 217 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DistinguishedNameSyntaxImpl.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java 1105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnhancedGuideSyntaxImpl.java 181 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumOrderingMatchingRule.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EnumSyntaxImpl.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/EqualLengthApproximateMatchingRuleImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/FacsimileNumberSyntaxImpl.java 238 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/FaxSyntaxImpl.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeEqualityMatchingRuleImpl.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeOrderingMatchingRuleImpl.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GeneralizedTimeSyntaxImpl.java 1411 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GenerateCoreSchema.java 407 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/GuideSyntaxImpl.java 427 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IA5StringSyntaxImpl.java 130 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerEqualityMatchingRuleImpl.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java 123 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerOrderingMatchingRuleImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/IntegerSyntaxImpl.java 227 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/JPEGSyntaxImpl.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/KeywordEqualityMatchingRuleImpl.java 179 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/LDAPSyntaxDescriptionSyntaxImpl.java 228 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRule.java 475 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleImpl.java 157 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleSyntaxImpl.java 215 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUse.java 372 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/MatchingRuleUseSyntaxImpl.java 218 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameAndOptionalUIDSyntaxImpl.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameForm.java 452 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NameFormSyntaxImpl.java 222 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringEqualityMatchingRuleImpl.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringOrderingMatchingRuleImpl.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSubstringMatchingRuleImpl.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/NumericStringSyntaxImpl.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OIDSyntaxImpl.java 108 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClass.java 797 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassSyntaxImpl.java 217 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectClassType.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierEqualityMatchingRuleImpl.java 179 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringEqualityMatchingRuleImpl.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringOrderingMatchingRuleImpl.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSubstringMatchingRuleImpl.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OctetStringSyntaxImpl.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/OtherMailboxSyntaxImpl.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PostalAddressSyntaxImpl.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressEqualityMatchingRuleImpl.java 85 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PresentationAddressSyntaxImpl.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/PrintableStringSyntaxImpl.java 248 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationEqualityMatchingRuleImpl.java 85 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/ProtocolInformationSyntaxImpl.java 113 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/RegexSyntaxImpl.java 127 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/Schema.java 2617 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaBuilder.java 3134 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaCompatOptions.java 162 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaConstants.java 1535 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaElement.java 189 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaException.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SchemaUtils.java 898 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SubstringAssertionSyntaxImpl.java 148 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SupportedAlgorithmSyntaxImpl.java 108 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/Syntax.java 430 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/SyntaxImpl.java 142 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberEqualityMatchingRuleImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSubstringMatchingRuleImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelephoneNumberSyntaxImpl.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TeletexTerminalIdentifierSyntaxImpl.java 268 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/TelexNumberSyntaxImpl.java 226 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UTCTimeSyntaxImpl.java 734 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDEqualityMatchingRuleImpl.java 130 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDOrderingMatchingRuleImpl.java 131 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UUIDSyntaxImpl.java 150 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UniqueMemberEqualityMatchingRuleImpl.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UnknownSchemaElementException.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordExactEqualityMatchingRuleImpl.java 78 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/UserPasswordSyntaxImpl.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/WordEqualityMatchingRuleImpl.java 179 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/org/opends/sdk/schema/package-info.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/javadoc/overview.html 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages.properties 5870 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_de.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_es.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_fr.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_ja.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_ko.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_zh_CN.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/resources/com/sun/opends/sdk/messages/messages_zh_TW.properties 531 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/controls/AccountUsabilityRequestControlTestCase.java 74 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/controls/AccountUsabilityResponseControlTestCase.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/LDAPDefaultTCPNIOTransportTestCase.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/ldap/LDAPTestCase.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/messages/MessagesTestCase.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/ASCIICharPropTestCase.java 183 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/Base64TestCase.java 238 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/StaticUtilsTestCase.java 227 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/StringPrepProfileTestCase.java 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/com/sun/opends/sdk/util/UtilTestCase.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/AttributeDescriptionTestCase.java 373 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteSequenceTestCase.java 247 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteStringBuilderTestCase.java 296 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ByteStringTestCase.java 195 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ConnectionFactoryTestCase.java 308 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/DNTestCase.java 980 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/EntriesTestCase.java 229 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/EntryTestCase.java 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/FilterTestCase.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPListenerTestCase.java 1062 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPServer.java 789 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LDAPUrlTestCase.java 232 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/LinkedAttributeTestCase.java 486 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/OpenDSTestCase.java 181 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/RDNTestCase.java 475 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SdkTestCase.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SuiteRunner.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/SynchronousConnectionTestCase.java 182 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TestCaseUtils.java 175 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TestListener.java 1429 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/TypesTestCase.java 156 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ByteSequenceReaderTestCase.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1InputStreamReaderTestCase.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1OutputStreamWriterTestCase.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1ReaderTestCase.java 922 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/asn1/ASN1WriterTestCase.java 742 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/controls/ControlsTestCase.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryReaderTestCase.java 152 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFEntryWriterTestCase.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/ldif/LDIFTestCase.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AbandonRequestTestCase.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AddRequestTestCase.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/AnonymousSASLBindRequestTestCase.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/BindRequestTestCase.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/CRAMMD5SASLBindRequestTestCase.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/CompareRequestTestCase.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/DeleteRequestTestCase.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/DigestMD5SASLBindRequestTestCase.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ExtendedRequestTestCase.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ExternalSASLBindRequestTestCase.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/GSSAPISASLBindRequestTestCase.java 111 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/GenericBindRequestTestCase.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyDNRequestTestCase.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/ModifyRequestTestCase.java 75 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/PlainSASLBindRequestTestCase.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestTestCase.java 136 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/RequestsTestCase.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/SimpleBindRequestTestCase.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/requests/UnbindRequestTestCase.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/responses/ResponsesTestCase.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AbstractSchemaElementTestCase.java 197 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/ApproximateMatchingRuleTest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeSyntaxTest.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/AttributeTypeTest.java 648 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java 78 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BitStringSyntaxTest.java 64 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java 85 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java 85 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java 149 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java 76 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java 149 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java 79 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java 88 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java 161 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/CoreSchemaTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/DITContentRuleSyntaxTest.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleTest.java 213 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/EnumSyntaxTestCase.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java 74 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/GuideSyntaxTest.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/IA5StringSyntaxTest.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/LDAPSyntaxTest.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleSyntaxTest.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleTest.java 136 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/OrderingMatchingRuleTest.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/OtherMailboxSyntaxTest.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/RegexSyntaxTestCase.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaTestCase.java 42 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SchemaUtilsTest.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SubstringMatchingRuleTest.java 263 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/SyntaxTestCase.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/TelexSyntaxTest.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/UTCTimeSyntaxTest.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/test/java/org/opends/sdk/schema/UUIDSyntaxTest.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ApplicationKeyManager.java
New file
@@ -0,0 +1,335 @@
/*
 * 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;
    }
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Argument.java
New file
@@ -0,0 +1,789 @@
/*
 * 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);
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentException.java
New file
@@ -0,0 +1,86 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentGroup.java
New file
@@ -0,0 +1,208 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ArgumentParser.java
New file
@@ -0,0 +1,1919 @@
/*
 * 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);
    }
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthRate.java
New file
@@ -0,0 +1,774 @@
/*
 * 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);
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
New file
@@ -0,0 +1,473 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/BooleanArgument.java
New file
@@ -0,0 +1,126 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/CLIException.java
New file
@@ -0,0 +1,102 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConnectionFactoryProvider.java
New file
@@ -0,0 +1,911 @@
/*
 * 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());
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ConsoleApplication.java
New file
@@ -0,0 +1,586 @@
/*
 * 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);
    }
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/DataSource.java
New file
@@ -0,0 +1,589 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/FileBasedArgument.java
New file
@@ -0,0 +1,278 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/IntegerArgument.java
New file
@@ -0,0 +1,536 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPCompare.java
New file
@@ -0,0 +1,660 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPModify.java
New file
@@ -0,0 +1,798 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPPasswordModify.java
New file
@@ -0,0 +1,497 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/LDAPSearch.java
New file
@@ -0,0 +1,1298 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ModRate.java
New file
@@ -0,0 +1,429 @@
/*
 * 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);
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/MultiChoiceArgument.java
New file
@@ -0,0 +1,271 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/MultiColumnPrinter.java
New file
@@ -0,0 +1,547 @@
/*
 * 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, &quot;-&quot;);
 * String oneRow[] = new String[3];
 * oneRow[0] = &quot;User Name&quot;;
 * oneRow[1] = &quot;Email Address&quot;;
 * oneRow[2] = &quot;Phone Number&quot;;
 * mp.addTitle(oneRow);
 * oneRow[0] = &quot;Bob&quot;;
 * oneRow[1] = &quot;bob@foo.com&quot;;
 * oneRow[2] = &quot;123-4567&quot;;
 * mp.add(oneRow);
 * oneRow[0] = &quot;John&quot;;
 * oneRow[1] = &quot;john@foo.com&quot;;
 * oneRow[2] = &quot;456-7890&quot;;
 * 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, &quot;-&quot;);
 * 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] = &quot;Name&quot;;
 * oneRow[1] = &quot;&quot;;
 * oneRow[2] = &quot;Contact&quot;;
 * oneRow[3] = &quot;&quot;;
 * tp.addTitle(oneRow, span);
 * oneRow[0] = &quot;First&quot;;
 * oneRow[1] = &quot;Last&quot;;
 * oneRow[2] = &quot;Email&quot;;
 * oneRow[3] = &quot;Phone&quot;;
 * tp.addTitle(oneRow);
 * oneRow[0] = &quot;Bob&quot;;
 * oneRow[1] = &quot;Jones&quot;;
 * oneRow[2] = &quot;bob@foo.com&quot;;
 * oneRow[3] = &quot;123-4567&quot;;
 * tp.add(oneRow);
 * oneRow[0] = &quot;John&quot;;
 * oneRow[1] = &quot;Doe&quot;;
 * oneRow[2] = &quot;john@foo.com&quot;;
 * oneRow[3] = &quot;456-7890&quot;;
 * 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 &lt; 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(" ");
    }
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java
New file
@@ -0,0 +1,171 @@
/*
 * 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);
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PerformanceRunner.java
New file
@@ -0,0 +1,1283 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/PromptingTrustManager.java
New file
@@ -0,0 +1,482 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/SearchRate.java
New file
@@ -0,0 +1,525 @@
/*
 * 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);
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/StringArgument.java
New file
@@ -0,0 +1,147 @@
/*
 * 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;
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/ToolConstants.java
New file
@@ -0,0 +1,619 @@
/*
 * 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()
  {
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/Utils.java
New file
@@ -0,0 +1,733 @@
/*
 * 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|:&lt;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.
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/main/java/com/sun/opends/sdk/tools/package-info.java
New file
@@ -0,0 +1,34 @@
/*
 * 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;
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/test/java/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactoryTestCase.java
New file
@@ -0,0 +1,73 @@
/*
 * 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.
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-client-tools/src/test/java/com/sun/opends/sdk/tools/ToolsTestCase.java
New file
@@ -0,0 +1,45 @@
/*
 * 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
{
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/AccountUsabilityRequestControl.java
New file
@@ -0,0 +1,191 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/AccountUsabilityResponseControl.java
New file
@@ -0,0 +1,570 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/RealAttributesOnlyRequestControl.java
New file
@@ -0,0 +1,192 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/VirtualAttributesOnlyRequestControl.java
New file
@@ -0,0 +1,192 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/controls/package-info.java
New file
@@ -0,0 +1,34 @@
/*
 * 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;
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetConnectionIDExtendedRequest.java
New file
@@ -0,0 +1,249 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetConnectionIDExtendedResult.java
New file
@@ -0,0 +1,183 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/GetSymmetricKeyExtendedRequest.java
New file
@@ -0,0 +1,335 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateExtendedRequest.java
New file
@@ -0,0 +1,1140 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateExtendedResult.java
New file
@@ -0,0 +1,171 @@
/*
 * 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();
  }
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperation.java
New file
@@ -0,0 +1,56 @@
/*
 * 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();
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperationContainer.java
New file
@@ -0,0 +1,53 @@
/*
 * 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();
}
opendj-sdk/opendj3/opendj-modules/opendj-sdk/src/main/java/com/sun/opends/sdk/extensions/PasswordPolicyStateOperationType.java
New file
@@ -0,0 +1,323 @@
/*
 * 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;
  }
}
Diff truncated after the above file
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