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

Bruno Lavit
07.45.2016 23ba57a9c731b332e1e349d623f438d81b04994b
Merge branch 'opendj-sdk'
915 files added
226109 ■■■■■ changed files
opendj-sdk/opendj-cli/pom.xml 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ApplicationKeyManager.java 261 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java 522 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentConstants.java 390 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentException.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentGroup.java 154 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java 1678 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/BooleanArgument.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CliConstants.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ClientException.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CommandBuilder.java 275 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CommonArguments.java 1138 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ConnectionFactoryProvider.java 841 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ConsoleApplication.java 767 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java 124 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/FileBasedArgument.java 169 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/HelpCallback.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/IntegerArgument.java 139 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Menu.java 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuBuilder.java 701 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuCallback.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuResult.java 253 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java 150 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiColumnPrinter.java 519 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/PromptingTrustManager.java 388 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ReturnCode.java 218 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/StringArgument.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java 355 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java 1219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TabSeparatedTablePrinter.java 137 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TableBuilder.java 319 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TablePrinter.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TableSerializer.java 124 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TextTablePrinter.java 449 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolVersionHandler.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Utils.java 740 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ValidationCallback.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/VersionHandler.java 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/package-info.java 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli.properties 463 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ca_ES.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_de.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_es.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_fr.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ja.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ko.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_pl.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_zh_CN.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_zh_TW.properties 17 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgAppendProps.ftl 24 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgListItem.ftl 25 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgListSubtypes.ftl 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgReference.ftl 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgSubcommand.ftl 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgVarListEntry.ftl 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgVariableList.ftl 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/optionsRefSect1.ftl 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/refEntry.ftl 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/refSect1.ftl 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/main/resources/templates/refSect2.ftl 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/CliTestCase.java 28 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/ConsoleApplicationTestCase.java 195 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/TestSubCommandArgumentParserTestCase.java 160 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/TestSubCommandTestCase.java 249 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/UtilsTestCase.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/clirr-ignored-api-changes.xml 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/pom.xml 312 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControl.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControl.java 451 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/RealAttributesOnlyRequestControl.java 130 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/TransactionIdControl.java 131 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/VirtualAttributesOnlyRequestControl.java 130 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedRequest.java 169 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedResult.java 124 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetSymmetricKeyExtendedRequest.java 228 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedRequest.java 696 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedResult.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperation.java 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperationContainer.java 56 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperationType.java 186 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java 316 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java 260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java 325 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java 341 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/OperatingSystem.java 247 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/PackedLong.java 235 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Predicate.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java 156 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/SizeLimitInputStream.java 136 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/StaticUtils.java 789 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java 508 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/SubstringReader.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1.java 327 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1ByteSequenceReader.java 400 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1InputStreamReader.java 550 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1OutputStreamWriter.java 336 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1Reader.java 421 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1Writer.java 356 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractASN1Reader.java 154 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractASN1Writer.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractLDAPMessageHandler.java 244 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAP.java 833 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPMessageHandler.java 389 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPReader.java 722 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPWriter.java 689 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/package-info.java 29 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java 744 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractAttribute.java 300 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java 440 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java 635 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractEntry.java 260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractFilterVisitor.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractMapEntry.java 123 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractSynchronousConnection.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java 512 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Assertion.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AssertionFailureException.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Attribute.java 438 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeDescription.java 1300 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFactory.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java 412 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java 669 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Attributes.java 592 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AuthenticationException.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AuthorizationException.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Base64.java 356 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java 366 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequenceReader.java 523 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java 958 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java 1152 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CachedConnectionPool.java 925 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CancelledResultException.java 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CommonLDAPOptions.java 127 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConditionResult.java 235 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connection.java 1453 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionEventListener.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionException.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionLoadBalancer.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionSecurityLayer.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java 835 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConstraintViolationException.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java 1046 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DecodeException.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DecodeOptions.java 181 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DereferenceAliasesPolicy.java 157 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java 1103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entry.java 522 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/EntryFactory.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/EntryNotFoundException.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Filter.java 1653 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FilterVisitor.java 192 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java 438 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/GSERParser.java 396 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java 992 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/InternalConnection.java 186 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java 88 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/KeyManagers.java 283 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPClientContext.java 162 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java 1224 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java 309 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPUrl.java 743 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapException.java 213 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapPromise.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapResultHandler.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LinkedAttribute.java 694 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LinkedHashMapEntry.java 164 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java 297 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Matcher.java 567 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java 623 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Modification.java 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ModificationType.java 193 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/MultipleEntriesFoundException.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java 576 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ReferralException.java 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestContext.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java 218 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java 682 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestLoadBalancer.java 251 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java 1000 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java 425 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SSLContextBuilder.java 212 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SchemaResolver.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchResultReferenceIOException.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchScope.java 204 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ServerConnection.java 88 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ServerConnectionFactory.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SortKey.java 538 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutChecker.java 170 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutEventListener.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutResultException.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TreeMapEntry.java 166 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TrustManagers.java 373 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ADNotificationRequestControl.java 158 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AssertionRequestControl.java 193 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityRequestControl.java 158 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityResponseControl.java 180 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/Control.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ControlDecoder.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/EntryChangeNotificationResponseControl.java 344 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/GenericControl.java 155 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/GetEffectiveRightsRequestControl.java 367 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ManageDsaITRequestControl.java 160 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/MatchedValuesRequestControl.java 353 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiredResponseControl.java 155 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiringResponseControl.java 177 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyErrorType.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyRequestControl.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java 354 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyWarningType.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PermissiveModifyRequestControl.java 158 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchChangeType.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchRequestControl.java 371 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PostReadRequestControl.java 284 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PostReadResponseControl.java 210 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PreReadRequestControl.java 285 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PreReadResponseControl.java 209 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV1RequestControl.java 220 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV2RequestControl.java 231 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortRequestControl.java 323 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortResponseControl.java 310 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SimplePagedResultsControl.java 315 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java 228 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SubtreeDeleteRequestControl.java 143 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewRequestControl.java 483 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewResponseControl.java 322 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/package-info.java 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequest.java 64 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequestImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractBindRequest.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractExtendedRequest.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractRequestImpl.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractSASLBindRequest.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableBindRequest.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableExtendedRequest.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableRequest.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableSASLBindRequest.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AddRequest.java 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AddRequestImpl.java 198 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequest.java 113 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindClient.java 78 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindClientImpl.java 104 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindRequest.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java 181 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequest.java 94 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequestImpl.java 164 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequest.java 176 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequestImpl.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequest.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequestImpl.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequest.java 466 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java 395 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequest.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequestDecoder.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequest.java 121 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java 136 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequest.java 433 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java 503 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequest.java 126 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequestImpl.java 121 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequest.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequestImpl.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequest.java 220 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestImpl.java 142 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequest.java 160 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequestImpl.java 118 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequest.java 212 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequestImpl.java 284 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequest.java 202 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java 182 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/Request.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/Requests.java 1608 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindClientImpl.java 194 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindRequest.java 79 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequest.java 324 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequestImpl.java 210 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequest.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestImpl.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequest.java 194 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequestImpl.java 185 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequest.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequestImpl.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAbandonRequestImpl.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAddRequestImpl.java 180 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAnonymousSASLBindRequestImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCancelExtendedRequestImpl.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCompareRequestImpl.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDeleteRequestImpl.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableExternalSASLBindRequestImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGSSAPISASLBindRequestImpl.java 152 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericBindRequestImpl.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericExtendedRequestImpl.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyDNRequestImpl.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyRequestImpl.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePlainSASLBindRequestImpl.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSearchRequestImpl.java 131 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSimpleBindRequestImpl.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableStartTLSExtendedRequestImpl.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableUnbindRequestImpl.java 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableWhoAmIExtendedRequestImpl.java 30 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequest.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequestImpl.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResult.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractIntermediateResponse.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResponseImpl.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResultImpl.java 126 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableExtendedResultImpl.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableIntermediateResponseImpl.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResponseImpl.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResultImpl.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/BindResult.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/BindResultImpl.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/CompareResult.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/CompareResultImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResult.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResultDecoder.java 111 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResult.java 120 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResultImpl.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponse.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponseImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/IntermediateResponse.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResult.java 131 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResultImpl.java 122 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Response.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Responses.java 537 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Result.java 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ResultImpl.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntry.java 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntryImpl.java 196 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReference.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReferenceImpl.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableBindResultImpl.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableCompareResultImpl.java 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericExtendedResultImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericIntermediateResponseImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiablePasswordModifyExtendedResultImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableResultImpl.java 26 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultEntryImpl.java 177 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultReferenceImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableWhoAmIExtendedResultImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResult.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResultImpl.java 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractApproximateMatchingRuleImpl.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractEqualityMatchingRuleImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java 115 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractOrderingMatchingRuleImpl.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImpl.java 532 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java 1094 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxImpl.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeUsage.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordExactEqualityMatchingRuleImpl.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordSyntaxImpl.java 253 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BinarySyntaxImpl.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleImpl.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxImpl.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleImpl.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BooleanSyntaxImpl.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleImpl.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleImpl.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleImpl.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListEqualityMatchingRuleImpl.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListSubstringMatchingRuleImpl.java 49 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleImpl.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactAssertionSyntaxImpl.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java 202 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateListSyntaxImpl.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificatePairSyntaxImpl.java 64 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxImpl.java 200 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java 333 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ConflictingSchemaElementException.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchema.java 2362 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java 1768 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaSupportedLocales.java 250 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxImpl.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java 868 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java 505 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRuleSyntaxImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DelayedSchema.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DeliveryMethodSyntaxImpl.java 118 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringSyntaxImpl.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameSyntaxImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java 942 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnhancedGuideSyntaxImpl.java 121 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumOrderingMatchingRule.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/FacsimileNumberSyntaxImpl.java 168 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/FaxSyntaxImpl.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeEqualityMatchingRuleImpl.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeOrderingMatchingRuleImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxImpl.java 73 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GenerateCoreSchema.java 328 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GuideSyntaxImpl.java 314 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxImpl.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerEqualityMatchingRuleImpl.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerOrderingMatchingRuleImpl.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerSyntaxImpl.java 170 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java 89 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java 134 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxDescriptionSyntaxImpl.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java 558 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleImpl.java 132 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxImpl.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java 490 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxImpl.java 142 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameAndOptionalUIDSyntaxImpl.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java 637 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameFormSyntaxImpl.java 154 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleImpl.java 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSyntaxImpl.java 88 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OIDSyntaxImpl.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java 961 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassSyntaxImpl.java 149 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassType.java 64 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java 76 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java 82 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringEqualityMatchingRuleImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringOrderingMatchingRuleImpl.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSubstringMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSyntaxImpl.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxImpl.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PostalAddressSyntaxImpl.java 62 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleImpl.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressSyntaxImpl.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PrintableStringSyntaxImpl.java 189 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleImpl.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationSyntaxImpl.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/RegexSyntaxImpl.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java 2211 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java 2664 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaConstants.java 761 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java 299 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaException.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaOptions.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java 776 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaValidationPolicy.java 425 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SubstringAssertionSyntaxImpl.java 94 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SupportedAlgorithmSyntaxImpl.java 66 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java 473 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SyntaxImpl.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberEqualityMatchingRuleImpl.java 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSubstringMatchingRuleImpl.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxImpl.java 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TeletexTerminalIdentifierSyntaxImpl.java 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelexNumberSyntaxImpl.java 150 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TimeBasedMatchingRulesImpl.java 588 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java 695 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDEqualityMatchingRuleImpl.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDOrderingMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxImpl.java 122 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UnknownSchemaElementException.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordExactEqualityMatchingRuleImpl.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordSyntaxImpl.java 154 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/BindResultLdapPromiseImpl.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ConnectionState.java 371 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ExtendedResultLdapPromiseImpl.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexQueryFactory.java 107 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/Indexer.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexingOptions.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java 71 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionImpl.java 314 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromiseImpl.java 82 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromiseWrapper.java 193 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromises.java 440 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ResultLdapPromiseImpl.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/SearchResultLdapPromiseImpl.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java 698 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFStream.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java 373 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecord.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordReader.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitor.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitorWriter.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordWriter.java 148 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionChangeRecordWriter.java 210 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java 394 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryWriter.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryGenerator.java 316 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryReader.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryWriter.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java 848 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordReader.java 740 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriter.java 392 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFEntryReader.java 420 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFEntryWriter.java 293 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/RejectedChangeRecordListener.java 219 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/RejectedLDIFListener.java 164 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateFile.java 2068 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java 1462 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/javadoc/overview.html 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties 1649 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_de.properties 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_es.properties 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_fr.properties 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_ja.properties 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_ko.properties 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_zh_CN.properties 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_zh_TW.properties 86 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/addrate.template 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/cities 232 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/example.template 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/first.names 8605 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/last.names 13419 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/people_and_groups.template 62 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/states 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/streets 74 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/site/xdoc/index.xml.vm 180 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControlTestCase.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControlTestCase.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/ASCIICharPropTestCase.java 257 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/OperatingSystemTestCase.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/ReferenceCountedObjectTestCase.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/StaticUtilsTestCase.java 332 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/StringPrepProfileTestCase.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/UtilTestCase.java 29 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1ByteSequenceReaderTestCase.java 32 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1InputStreamReaderTestCase.java 30 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1OutputStreamWriterTestCase.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1ReaderTestCase.java 789 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1WriterTestCase.java 595 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/LDAPReaderWriterTestCase.java 510 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java 83 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java 462 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java 242 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeDescriptionTestCase.java 544 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeParserTestCase.java 352 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributesTestCase.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteSequenceReaderTest.java 369 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java 160 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringBuilderTestCase.java 444 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java 363 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/CompactDnTestCase.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConditionResultTestCase.java 175 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConnectionPoolTestCase.java 539 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java 152 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java 1396 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DataProviderIterator.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/EntriesTestCase.java 476 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/EntryTestCase.java 812 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java 329 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/GSERParserTestCase.java 291 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/GeneralizedTimeTest.java 220 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactoryTestCase.java 508 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java 569 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPUrlTestCase.java 184 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LinkedAttributeTestCase.java 421 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LoadBalancerTestCase.java 179 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java 673 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java 93 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MockScheduler.java 260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ModificationTypeTestCase.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/PackedLongTestCase.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java 512 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RequestLoadBalancerTestCase.java 950 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ResultCodeTestCase.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/SdkTestCase.java 29 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/SearchScopeTestCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java 244 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/TestCaseUtilsTestCase.java 43 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/controls/ControlsTestCase.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AbandonRequestTestCase.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AddRequestTestCase.java 147 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestTestCase.java 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/BindRequestTestCase.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestTestCase.java 108 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequestTestCase.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CompareRequestTestCase.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/DeleteRequestTestCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestTestCase.java 203 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ExtendedRequestTestCase.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestTestCase.java 75 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestTestCase.java 201 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GenericBindRequestTestCase.java 105 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequestTestCase.java 104 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestTestCase.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ModifyRequestTestCase.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequestTestCase.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestTestCase.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/RequestsTestCase.java 214 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/SearchRequestTestCase.java 176 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestTestCase.java 98 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequestTestCase.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/UnbindRequestTestCase.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequestTestCase.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/responses/ResponsesTestCase.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaElementTestCase.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaTestCase.java 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImplTest.java 281 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java 58 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ApproximateMatchingRuleTest.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeBuilderTestCase.java 176 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java 547 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AuthPasswordSyntaxImplTest.java 76 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleTest.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleTest.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BooleanSyntaxTest.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleTest.java 50 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleTest.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleTest.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleTest.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleTest.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleTest.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java 112 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleTest.java 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleTest.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImplTest.java 203 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxTest.java 143 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java 106 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java 156 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CoreSchemaTest.java 31 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleTestCase.java 161 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITStructureRuleTestCase.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleTest.java 208 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EntrySchemaCheckingTestCase.java 1137 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java 80 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeEqualityMatchingRuleTest.java 76 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeOrderingMatchingRuleTest.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerEqualityMatchingRuleTest.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerOrderingMatchingRuleTest.java 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerSyntaxTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxTest.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java 77 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleTest.java 106 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleTestCase.java 744 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseBuilderTestCase.java 147 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java 45 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NameFormTestCase.java 1044 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleTest.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleTest.java 55 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleTest.java 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ObjectClassBuilderTestCase.java 198 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OrderingMatchingRuleTest.java 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/PartialDateAndTimeMatchingRuleTestCase.java 180 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleTest.java 47 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java 59 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RelativeTimeGreaterThanMatchingRuleTest.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RelativeTimeLessThanMatchingRuleTest.java 116 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java 2340 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaCompatTest.java 299 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaOptionsTestCase.java 75 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaTestCase.java 114 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaUtilsTest.java 252 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java 102 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstringMatchingRuleTest.java 217 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java 598 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxTest.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java 172 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDEqualityMatchingRuleTest.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDOrderingMatchingRuleTest.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleTest.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UserPasswordExactEqualityMatchingRuleTest.java 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/WordEqualityMatchingRuleTest.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicLDAPConnectionFactory.java 69 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicLDAPListener.java 75 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicTransportProvider.java 56 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/ConnectionStateTest.java 269 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/LDAPTestCase.java 30 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionChangeRecordWriterTestCase.java 388 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionEntryReaderTestCase.java 265 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionEntryWriterTestCase.java 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/EntryGeneratorTestCase.java 591 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordReaderTestCase.java 2489 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java 1405 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryReaderTestCase.java 1662 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java 826 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java 2823 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestcase.java 283 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider 15 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/pom.xml 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/CommandLineTool.java 167 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java 154 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateGlobalAcisTableMojo.java 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java 378 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateRefEntriesMojo.java 275 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java 174 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java 252 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java 239 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/package-info.java 20 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/duration-syntax.html 24 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/opendj-config.css 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/opendj_logo_sm.png patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/pageaction.gif patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/tab_deselected.jpg patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/tab_selected.gif patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/org/forgerock/opendj/maven/doc/docs.properties 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl 74 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/log-message-reference.ftl 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/sec-locales-subtypes.ftl 62 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/table-global-acis.ftl 60 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/pom.xml 146 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/com/forgerock/opendj/grizzly/GrizzlyTransportProvider.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/com/forgerock/opendj/grizzly/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferReader.java 572 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferWriter.java 445 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ConnectionSecurityLayerFilter.java 120 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransport.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnection.java 859 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionFactory.java 254 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListener.java 152 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyUtils.java 228 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPBaseFilter.java 121 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPClientFilter.java 496 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPServerFilter.java 878 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/package-info.java 38 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider 15 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/main/resources/com/forgerock/opendj/grizzly/grizzly.properties 24 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/site/xdoc/index.xml.vm 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ASN1BufferReaderTestCase.java 40 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ASN1BufferWriterTestCase.java 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java 703 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java 67 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionFactoryTestCase.java 447 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionTestCase.java 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java 709 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPReaderWriterTestCase.java 51 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyUtilsTestCase.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/pom.xml 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/assembly/examples.xml 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Controls.java 1076 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ExtendedOperations.java 197 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java 134 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetInfo.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java 122 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java 167 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ParseAttributes.java 153 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java 203 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java 260 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java 117 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java 438 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java 171 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java 125 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java 241 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java 139 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java 163 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java 217 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuth.java 314 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java 263 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroup.java 178 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java 218 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java 162 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java 173 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/package-info.java 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/main/javadoc/overview.html 7 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm 188 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-sdk-examples/src/test/bin/checkRewriterProxy.sh 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/README 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/legal-notices/THIRDPARTYREADME.txt 338 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/pom.xml 327 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/addrate.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/authrate.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapcompare.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapmodify.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldappasswordmodify.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapsearch.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifdiff.bat 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifmodify.bat 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifsearch.bat 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/makeldif.bat 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/modrate.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/searchrate.bat 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/addrate 25 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/authrate 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapcompare 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapmodify 28 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldappasswordmodify 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapsearch 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifdiff 26 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifmodify 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifsearch 26 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/makeldif 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/modrate 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/searchrate 27 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/descriptor.xml 110 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/_client-script.bat 42 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/_script-util.bat 145 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/setcp.bat 29 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbin/_client-script.sh 54 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbin/_script-util.sh 119 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/assembly/man-pages.xml 94 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java 542 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java 516 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/DataSource.java 416 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java 387 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java 463 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java 288 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java 842 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFDiff.java 197 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFModify.java 290 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFSearch.java 280 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/MakeLDIF.java 290 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java 244 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java 503 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunnerOptions.java 70 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java 317 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/StatsThread.java 418 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/Utils.java 267 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties 372 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ca_ES.properties 20 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_de.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_es.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_fr.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ja.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ko.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_pl.properties 20 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_zh_CN.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_zh_TW.properties 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/site/xdoc/index.xml.vm 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AddRateITCase.java 124 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java 82 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java 63 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java 94 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/MakeLDIFITCase.java 168 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsITCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestCase.java 30 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/resources/dummy-truststore patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/resources/expected_output.ldif 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/resources/expected_output_80_column.ldif 14 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/resources/invalid_test_template.ldif 29 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-ldap-toolkit/src/test/resources/valid_test_template.ldif 28 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/README 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/pom.xml 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java 390 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java 197 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthenticatedConnectionContext.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthorizationPolicy.java 42 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthzIdTemplate.java 149 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java 135 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/FilterType.java 85 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/HttpAuthenticationFilter.java 385 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java 151 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java 1054 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/NameStrategy.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java 339 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReadOnUpdatePolicy.java 48 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java 372 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/RequestState.java 435 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java 1126 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java 167 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java 182 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java 223 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/WritabilityPolicy.java 79 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/package-info.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/main/resources/META-INF/services/org.forgerock.http.HttpApplication 16 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/site/xdoc/index.xml.vm 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/AuthzIdTemplateTest.java 133 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java 776 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/TestUtils.java 96 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-sdk-bom/pom.xml 101 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-cli/pom.xml
New file
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2014-2016 ForgeRock AS.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>opendj-sdk-parent</artifactId>
        <groupId>org.forgerock.opendj</groupId>
        <version>4.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>opendj-cli</artifactId>
    <name>OpenDJ CLI API</name>
    <description>This module includes CLI API for implementing CLI applications.</description>
    <packaging>bundle</packaging>
    <dependencies>
        <dependency>
            <groupId>org.forgerock.opendj</groupId>
            <artifactId>opendj-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.forgerock.opendj</groupId>
            <artifactId>opendj-core</artifactId>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.forgerock.commons</groupId>
            <artifactId>i18n-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.forgerock</groupId>
            <artifactId>forgerock-build-tools</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.21</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <properties>
        <opendj.osgi.import.additional>
            org.forgerock.opendj.*;provide:=true
        </opendj.osgi.import.additional>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.forgerock.commons</groupId>
                <artifactId>i18n-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-messages</goal>
                        </goals>
                        <configuration>
                            <messageFiles>
                                <messageFile>com/forgerock/opendj/cli/cli.properties</messageFile>
                            </messageFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>cobertura-maven-plugin</artifactId>
            </plugin>
            <!-- Creates opendj-cli bundle -->
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <configuration>
                    <instructions>
                        <Export-Package>com.forgerock.opendj.cli</Export-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <reportSets>
                    <reportSet>
                        <reports>
                            <report>mailing-list</report>
                            <report>issue-tracking</report>
                            <report>license</report>
                            <report>cim</report>
                            <report>distribution-management</report>
                        </reports>
                    </reportSet>
                </reportSets>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                    <links>
                        <link>http://commons.forgerock.org/i18n-framework/i18n-core/apidocs</link>
                    </links>
                </configuration>
            </plugin>
        </plugins>
    </reporting>
</project>
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ApplicationKeyManager.java
New file
@@ -0,0 +1,261 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008-2010 Sun Microsystems, Inc.
 * Portions Copyright 2009 Parametric Technology Corporation (PTC)
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.net.Socket;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
/**
 * 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 {
    private static final LocalizedLogger LOG = LocalizedLogger.getLoggerForThisClass();
    /**
     * The default keyManager.
     */
    private X509KeyManager keyManager;
    /**
     * The default constructor.
     *
     * @param keystore
     *            The key store to use for this key manager.
     * @param password
     *            The key store password to use for this key manager.
     */
    ApplicationKeyManager(final KeyStore keystore, final char[] password) {
        KeyManagerFactory kmf = null;
        String userSpecifiedAlgo = System.getProperty("org.opendj.admin.keymanageralgo");
        String userSpecifiedProvider = System.getProperty("org.opendj.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 fall backs to choose the provider and algorithm of the
        // key manager. First see if the user wanted to use something
        // specific, then try with the SunJSSE provider and SunX509
        // algorithm. Finally, fall back 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 key managers, look for an instance
                 * of X509KeyManager. If found, use that as our "default" key
                 * manager.
                 */
                for (final KeyManager km : kms) {
                    if (km 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 effort mode.
                LOG.warn(LocalizableMessage.raw("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 effort mode..
                LOG.warn(LocalizableMessage.raw("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 effort mode.
                LOG.warn(LocalizableMessage.raw("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 effort mode.
                LOG.warn(LocalizableMessage.raw("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.
     */
    @Override
    public String chooseClientAlias(final String[] keyType, final Principal[] issuers,
            final Socket socket) {
        if (keyManager != null) {
            return keyManager.chooseClientAlias(keyType, issuers, socket);
        }
        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.
     */
    @Override
    public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
        if (keyManager != null) {
            return keyManager.chooseServerAlias(keyType, issuers, socket);
        }
        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.
     */
    @Override
    public X509Certificate[] getCertificateChain(final String alias) {
        if (keyManager != null) {
            return keyManager.getCertificateChain(alias);
        }
        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.
     */
    @Override
    public String[] getClientAliases(final String keyType, final Principal[] issuers) {
        if (keyManager != null) {
            return keyManager.getClientAliases(keyType, issuers);
        }
        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.
     */
    @Override
    public PrivateKey getPrivateKey(final String alias) {
        if (keyManager != null) {
            return keyManager.getPrivateKey(alias);
        }
        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.
     */
    @Override
    public String[] getServerAliases(final String keyType, final Principal[] issuers) {
        if (keyManager != null) {
            return keyManager.getServerAliases(keyType, issuers);
        }
        return null;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java
New file
@@ -0,0 +1,522 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.util.Reject;
/**
 * 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.
 */
public abstract class Argument implements DocDescriptionSupplement {
    /**
     * An abstract base class to build a generic {@link Argument}.
     *
     * @param <B>
     *         The concrete {@link ArgumentBuilder} subclass.
     * @param <T>
     *         The default value type of the {@link Argument}.
     * @param <A>
     *         The concrete {@link Argument} type to build.
     */
    static abstract class ArgumentBuilder<B extends ArgumentBuilder<B, T, A>, T, A extends Argument> {
        T defaultValue;
        LocalizableMessage description;
        LocalizableMessage docDescriptionSupplement;
        boolean hidden;
        final String longIdentifier;
        boolean multiValued;
        boolean needsValue = true;
        boolean required;
        Character shortIdentifier;
        LocalizableMessage valuePlaceholder;
        ArgumentBuilder(final String longIdentifier) {
            Reject.ifNull(longIdentifier, "An argument must have a long identifier");
            this.longIdentifier = longIdentifier;
        }
        abstract B getThis();
        /**
         * Build the argument.
         *
         * @return The argument built.
         * @throws ArgumentException
         *         If there is a problem with any of the parameters used to
         *         create this argument.
         */
        public abstract A buildArgument() throws ArgumentException;
        /**
         * Build the argument and add it to the provided {@link ArgumentParser}.
         *
         * @param parser
         *         The argument parser.
         * @return The argument built.
         * @throws ArgumentException
         *         If there is a problem with any of the parameters used to
         *         create this argument.
         */
        public A buildAndAddToParser(final ArgumentParser parser) throws ArgumentException {
            final A arg = buildArgument();
            parser.addArgument(arg);
            return arg;
        }
        /**
         * Build the argument and add it to the provided {@link SubCommand}.
         *
         * @param subCommand
         *         The sub command.
         * @return The argument built.
         * @throws ArgumentException
         *         If there is a problem with any of the parameters used to
         *         create this argument.
         */
        public A buildAndAddToSubCommand(final SubCommand subCommand) throws ArgumentException {
            final A arg = buildArgument();
            subCommand.addArgument(arg);
            return arg;
        }
        /**
         * Sets this argument default value.
         *
         * @param defaultValue
         *         The default value.
         * @return This builder.
         */
        public B defaultValue(final T defaultValue) {
            this.defaultValue = defaultValue;
            return getThis();
        }
        /**
         * Sets this argument description.
         *
         * @param description
         *         The localized description.
         * @return This builder.
         */
        public B description(final LocalizableMessage description) {
            this.description = description;
            return getThis();
        }
        /**
         * Sets a supplement to the description intended for use in generated reference documentation.
         *
         * @param docDescriptionSupplement
         *         The supplement to the description for use in generated reference documentation.
         * @return This builder.
         */
        public B docDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
            this.docDescriptionSupplement = docDescriptionSupplement;
            return getThis();
        }
        /**
         * Specifies that this argument is hidden.
         *
         * @return This builder.
         */
        public B hidden() {
            this.hidden = true;
            return getThis();
        }
        /**
         * Specifies that this argument may have multiple values.
         *
         * @return This builder.
         */
        public B multiValued() {
            this.multiValued = true;
            return getThis();
        }
        /**
         * Specifies that this argument is required.
         *
         * @return This builder.
         */
        public B required() {
            this.required = true;
            return getThis();
        }
        /**
         * Sets this argument single-character identifier.
         *
         * @param shortIdentifier
         *         The single-character identifier.
         * @return This builder.
         */
        public B shortIdentifier(final Character shortIdentifier) {
            this.shortIdentifier = shortIdentifier;
            return getThis();
        }
        /**
         * Sets this argument value placeholder, which will be used in usage information.
         *
         * @param valuePlaceholder
         *         The localized value placeholder.
         * @return This builder.
         */
        public B valuePlaceholder(final LocalizableMessage valuePlaceholder) {
            this.valuePlaceholder = valuePlaceholder;
            return getThis();
        }
    }
    /** The long identifier for this argument. */
    final String longIdentifier;
    /** The single-character identifier for this argument. */
    private final Character shortIdentifier;
    /** The unique ID of the description for this argument. */
    private final LocalizableMessage description;
    /** Indicates whether this argument should be hidden in the usage information. */
    private final boolean isHidden;
    /** Indicates whether this argument may be specified more than once for multiple values. */
    private final boolean isMultiValued;
    /** Indicates whether this argument is required to have a value. */
    private final boolean isRequired;
    /** Indicates whether this argument requires a value. */
    private final boolean needsValue;
    /** The default value for the argument if none other is provided. */
    private final String defaultValue;
    /** The value placeholder for this argument, which will be used in usage information. */
    private final LocalizableMessage valuePlaceholder;
    /** The set of values for this argument. */
    private final LinkedList<String> values = new LinkedList<>();
    /** Indicates whether this argument was provided in the set of command-line arguments. */
    private boolean isPresent;
    /**
     * Indicates whether this argument was provided in the set of
     * properties found in a properties file.
     */
    private boolean isValueSetByProperty;
    <B extends ArgumentBuilder<B, T, A>, T, A extends Argument> Argument(final ArgumentBuilder<B, T, A> builder)
            throws ArgumentException {
        this.shortIdentifier = builder.shortIdentifier;
        this.longIdentifier = builder.longIdentifier;
        this.isRequired = builder.required;
        this.isMultiValued = builder.multiValued;
        this.needsValue = builder.needsValue;
        this.valuePlaceholder = builder.valuePlaceholder;
        this.defaultValue = builder.defaultValue != null ? String.valueOf(builder.defaultValue) : null;
        this.description = builder.description;
        this.isHidden = builder.hidden;
        this.docDescriptionSupplement = builder.docDescriptionSupplement;
        if (needsValue && valuePlaceholder == null) {
            throw new ArgumentException(ERR_ARG_NO_VALUE_PLACEHOLDER.get(longIdentifier));
        }
        isPresent = 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) {
        if (!isMultiValued) {
            clearValues();
        }
        values.add(valueString);
    }
    /**
     * Clears the set of values assigned to this argument.
     */
    public void clearValues() {
        values.clear();
    }
    /**
     * 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;
    }
    /** A supplement to the description intended for use in generated reference documentation. */
    private LocalizableMessage docDescriptionSupplement;
    @Override
    public LocalizableMessage getDocDescriptionSupplement() {
        return docDescriptionSupplement != null ? docDescriptionSupplement : 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 int getIntValue() throws ArgumentException {
        if (values.isEmpty()) {
            throw new ArgumentException(ERR_ARG_NO_INT_VALUE.get(longIdentifier));
        }
        final Iterator<String> iterator = values.iterator();
        final String valueString = iterator.next();
        if (iterator.hasNext()) {
            throw new ArgumentException(ERR_ARG_INT_MULTIPLE_VALUES.get(longIdentifier));
        }
        try {
            return Integer.parseInt(valueString);
        } catch (final Exception e) {
            throw new ArgumentException(ERR_ARG_CANNOT_DECODE_AS_INT.get(valueString, longIdentifier), e);
        }
    }
    /**
     * 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 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() {
        return !values.isEmpty() ? values.getFirst() : defaultValue;
    }
    /**
     * 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 List<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 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;
    }
    void valueSetByProperty() {
        isValueSetByProperty = true;
    }
    /**
     * 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);
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append("(");
        if (longIdentifier != null) {
            sb.append("longID=");
            sb.append(longIdentifier);
        }
        if (shortIdentifier != null) {
            if (longIdentifier != null) {
                sb.append(", ");
            }
            sb.append("shortID=");
            sb.append(shortIdentifier);
        }
        sb.append(", values=").append(values);
        sb.append(")");
        return sb.toString();
    }
    @Override
    public boolean equals(final Object arg) {
        return this == arg || (arg instanceof Argument && ((Argument) arg).longIdentifier.equals(this.longIdentifier));
    }
    @Override
    public int hashCode() {
        return longIdentifier.hashCode();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentConstants.java
New file
@@ -0,0 +1,390 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * This class contains short and long options used by the argument in CLI.
 */
public final class ArgumentConstants {
    /**
     * The name of the SASL property that can be used to provide the
     * authentication ID for the bind.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public static final String SASL_PROPERTY_QOP = "qop";
    /**
     * The name of the SASL property that can be used to provide the realm for
     * the bind.
     */
    public static final String SASL_PROPERTY_REALM = "realm";
    /**
     * The name of the SASL property that can be used to provide the SASL
     * mechanism to use.
     */
    public static final String SASL_PROPERTY_MECH = "mech";
    /** The value for the long option batch. */
    public static final String OPTION_LONG_BATCH = "batch";
    /** The value for the short option batchFilePath. */
    public static final char OPTION_SHORT_BATCH_FILE_PATH = 'F';
    /** The value for the long option batchFilePath. */
    public static final String OPTION_LONG_BATCH_FILE_PATH = "batchFilePath";
    /** The value for the short option host name. */
    public static final char OPTION_SHORT_HOST = 'h';
    /** The value for the long option host name. */
    public static final String OPTION_LONG_HOST = "hostname";
    /** The value for the short option port. */
    public static final char OPTION_SHORT_PORT = 'p';
    /** The value for the long option port. */
    public static final String OPTION_LONG_PORT = "port";
    /** The value for the short option useSSL. */
    public static final char OPTION_SHORT_USE_SSL = 'Z';
    /** The value for the long option useSSL. */
    public static final String OPTION_LONG_USE_SSL = "useSSL";
    /** The value for the short option baseDN. */
    public static final char OPTION_SHORT_BASEDN = 'b';
    /** The value for the long option baseDN. */
    public static final String OPTION_LONG_BASEDN = "baseDN";
    /** The value for the short option bindDN. */
    public static final char OPTION_SHORT_BINDDN = 'D';
    /** The value for the long option bindDN. */
    public static final String OPTION_LONG_BINDDN = "bindDN";
    /** The value for the short option bindPassword. */
    public static final char OPTION_SHORT_BINDPWD = 'w';
    /** The value for the long option bindPassword. */
    public static final String OPTION_LONG_BINDPWD = "bindPassword";
    /** The value for the short option bindPasswordFile. */
    public static final char OPTION_SHORT_BINDPWD_FILE = 'j';
    /** The value for the long option bindPasswordFile. */
    public static final String OPTION_LONG_BINDPWD_FILE = "bindPasswordFile";
    /** The value for the short option compress. */
    public static final char OPTION_SHORT_COMPRESS = 'c';
    /** The value for the long option compress. */
    public static final String OPTION_LONG_COMPRESS = "compress";
    /** The value for the short option filename. */
    public static final char OPTION_SHORT_FILENAME = 'f';
    /** The value for the long option filename. */
    public static final String OPTION_LONG_FILENAME = "filename";
    /** The value for the short option ldifFile. */
    public static final char OPTION_SHORT_LDIF_FILE = 'l';
    /** The value for the long option ldifFile. */
    public static final String OPTION_LONG_LDIF_FILE = "ldifFile";
    /** The value for the short option useStartTLS. */
    public static final char OPTION_SHORT_START_TLS = 'q';
    /** The value for the long option useStartTLS. */
    public static final String OPTION_LONG_START_TLS = "useStartTLS";
    /** The value for the short option randomSeed. */
    public static final char OPTION_SHORT_RANDOM_SEED = 's';
    /** The value for the long option randomSeed. */
    public static final String OPTION_LONG_RANDOM_SEED = "randomSeed";
    /** The value for the short option keyStorePath. */
    public static final char OPTION_SHORT_KEYSTOREPATH = 'K';
    /** The value for the long option keyStorePath. */
    public static final String OPTION_LONG_KEYSTOREPATH = "keyStorePath";
    /** The value for the short option trustStorePath. */
    public static final char OPTION_SHORT_TRUSTSTOREPATH = 'P';
    /** The value for the long option trustStorePath. */
    public static final String OPTION_LONG_TRUSTSTOREPATH = "trustStorePath";
    /** The value for the short option keyStorePassword. */
    public static final char OPTION_SHORT_KEYSTORE_PWD = 'W';
    /** The value for the long option keyStorePassword. */
    public static final String OPTION_LONG_KEYSTORE_PWD = "keyStorePassword";
    /** The value for the short option trustStorePassword. */
    public static final char OPTION_SHORT_TRUSTSTORE_PWD = 'T';
    /** The value for the long option trustStorePassword. */
    public static final String OPTION_LONG_TRUSTSTORE_PWD = "trustStorePassword";
    /** The value for the short option keyStorePasswordFile . */
    public static final char OPTION_SHORT_KEYSTORE_PWD_FILE = 'u';
    /** The value for the long option keyStorePasswordFile . */
    public static final String OPTION_LONG_KEYSTORE_PWD_FILE = "keyStorePasswordFile";
    /** The value for the short option keyStorePasswordFile . */
    public static final char OPTION_SHORT_TRUSTSTORE_PWD_FILE = 'U';
    /** The value for the long option keyStorePasswordFile . */
    public static final String OPTION_LONG_TRUSTSTORE_PWD_FILE = "trustStorePasswordFile";
    /** The value for the short option trustAll . */
    public static final char OPTION_SHORT_TRUSTALL = 'X';
    /** The value for the long option trustAll . */
    public static final String OPTION_LONG_TRUSTALL = "trustAll";
    /** The value for the short option certNickname . */
    public static final char OPTION_SHORT_CERT_NICKNAME = 'N';
    /** The value for the long option certNickname . */
    public static final String OPTION_LONG_CERT_NICKNAME = "certNickname";
    /** The value for the long option assertionFilter . */
    public static final String OPTION_LONG_ASSERTION_FILE = "assertionFilter";
    /** The value for the short option dry-run. */
    public static final char OPTION_SHORT_DRYRUN = 'n';
    /** The value for the long option dry-run. */
    public static final String OPTION_LONG_DRYRUN = "dry-run";
    /** The value for the short option help. */
    public static final char OPTION_SHORT_HELP = 'H';
    /** The value for the long option help. */
    public static final String OPTION_LONG_HELP = "help";
    /** The value for the long option cli. */
    public static final String OPTION_LONG_CLI = "cli";
    /** The value for the short option cli. */
    public static final char OPTION_SHORT_CLI = 'i';
    /** The value for the short option proxyAs. */
    public static final char OPTION_SHORT_PROXYAUTHID = 'Y';
    /** The value for the long option proxyAs. */
    public static final String OPTION_LONG_PROXYAUTHID = "proxyAs";
    /** The value for the short option saslOption. */
    public static final char OPTION_SHORT_SASLOPTION = 'o';
    /** The value for the long option saslOption. */
    public static final String OPTION_LONG_SASLOPTION = "saslOption";
    /** The value for the short option searchScope. */
    public static final  char OPTION_SHORT_SEARCHSCOPE = 's';
    /** The value for the long option searchScope. */
    public static final String OPTION_LONG_SEARCHSCOPE = "searchScope";
    /** The value for the short option geteffectiverights control authzid. */
    public static final char OPTION_SHORT_EFFECTIVERIGHTSUSER = 'g';
    /** The value for the long option geteffectiverights control authzid. */
    public static final String OPTION_LONG_EFFECTIVERIGHTSUSER = "getEffectiveRightsAuthzid";
    /** The value for the short option geteffectiveights control attributes. */
    public static final char OPTION_SHORT_EFFECTIVERIGHTSATTR = 'e';
    /**
     * The value for the long option geteffectiverights control specific
     * attribute list.
     */
    public static final String OPTION_LONG_EFFECTIVERIGHTSATTR = "getEffectiveRightsAttribute";
    /** The value for the short option protocol version attributes. */
    public static final char OPTION_SHORT_PROTOCOL_VERSION = 'V';
    /** The value for the long option protocol version attribute. */
    public static final String OPTION_LONG_PROTOCOL_VERSION = "ldapVersion";
    /** The value for the long option version. */
    public static final char OPTION_SHORT_PRODUCT_VERSION = 'V';
    /** The value for the long option version. */
    public static final String OPTION_LONG_PRODUCT_VERSION = "version";
    /** The value for the long "checkStoppability" {@link Argument}. */
    public static final String OPTION_LONG_CHECK_STOPPABILITY = "checkStoppability";
    /** The value for the long "windowsNetStop" {@link Argument}. */
    public static final String OPTION_LONG_WINDOWS_NET_STOP = "windowsNetStop";
    /** Value for the quiet option short form. */
    public static final Character OPTION_SHORT_QUIET = 'Q';
    /** Value for the quiet option long form. */
    public static final String OPTION_LONG_QUIET = "quiet";
    /** Value for non-interactive session short form. */
    public static final Character OPTION_SHORT_NO_PROMPT = 'n';
    /** Value for non-interactive session long form. */
    public static final String OPTION_LONG_NO_PROMPT = "no-prompt";
    /** Long form of script friendly option. */
    public static final String OPTION_LONG_SCRIPT_FRIENDLY = "script-friendly";
    /** Short form of script friendly option. */
    public static final Character OPTION_SHORT_SCRIPT_FRIENDLY = 's';
    /** Value for verbose option short form. */
    public static final Character OPTION_SHORT_VERBOSE = 'v';
    /** Value for verbose option long form. */
    public static final String OPTION_LONG_VERBOSE = "verbose";
    /** The value for the long option propertiesFilePAth . */
    public static final String OPTION_LONG_PROP_FILE_PATH = "propertiesFilePath";
    /** The value for the long option propertiesFilePAth . */
    public static final String OPTION_LONG_NO_PROP_FILE = "noPropertiesFile";
    /** Long form of referenced host name. */
    public static final String OPTION_LONG_REFERENCED_HOST_NAME = "referencedHostName";
    /** Long form of admin UID. */
    public static final String OPTION_LONG_ADMIN_UID = "adminUID";
    /** Long form of report authorization ID connection option. */
    public static final String OPTION_LONG_REPORT_AUTHZ_ID = "reportAuthzID";
    /** Long form of use password policy control connection option. */
    public static final String OPTION_LONG_USE_PW_POLICY_CTL = "usePasswordPolicyControl";
    /** Long form of use SASL external connection option. */
    public static final String OPTION_LONG_USE_SASL_EXTERNAL = "useSASLExternal";
    /** Long form of option for the command-line encoding option. */
    public static final String OPTION_LONG_ENCODING = "encoding";
    /** Long form of option specifying no wrapping of the command-line. */
    public static final String OPTION_LONG_DONT_WRAP = "dontWrap";
    /** The value for the long option targetDN. */
    public static final String OPTION_LONG_TARGETDN = "targetDN";
    /** Long form of email notification upon completion option. */
    public static final String OPTION_LONG_COMPLETION_NOTIFICATION_EMAIL = "completionNotify";
    /** Short form of email notification upon completion option. */
    public static final Character OPTION_SHORT_COMPLETION_NOTIFICATION_EMAIL = null;
    /** Long form of email notification upon error option. */
    public static final String OPTION_LONG_ERROR_NOTIFICATION_EMAIL = "errorNotify";
    /** Short form of email notification upon error option. */
    public static final Character OPTION_SHORT_ERROR_NOTIFICATION_EMAIL = null;
    /** Long form of dependency option. */
    public static final String OPTION_LONG_DEPENDENCY = "dependency";
    /** Short form of dependency option. */
    public static final Character OPTION_SHORT_DEPENDENCY = null;
    /** Long form of failed dependency action option. */
    public static final String OPTION_LONG_FAILED_DEPENDENCY_ACTION = "failedDependencyAction";
    /** Short form of failed dependency action option. */
    public static final Character OPTION_SHORT_FAILED_DEPENDENCY_ACTION = null;
    /** The default separator to be used in tables. */
    public static final String LIST_TABLE_SEPARATOR = ":";
    /** The value for the short option output LDIF filename. */
    public static final char OPTION_SHORT_OUTPUT_LDIF_FILENAME = 'o';
    /** The value for the long option output LDIF filename. */
    public static final String OPTION_LONG_OUTPUT_LDIF_FILENAME = "outputLDIF";
    /** The value for the long option to automatically accept the license if present. */
    public static final String OPTION_LONG_ACCEPT_LICENSE = "acceptLicense";
    /** The value for the short option rootUserDN. */
    public static final char OPTION_SHORT_ROOT_USER_DN = 'D';
    /** The value for the long option rootUserDN. */
    public static final String OPTION_LONG_ROOT_USER_DN = "rootUserDN";
    /** The value for the long option connect timeout attribute. */
    public static final String OPTION_LONG_CONNECT_TIMEOUT = "connectTimeout";
    /** The value for the long option advanced. */
    public static final String OPTION_LONG_ADVANCED = "advanced";
    /** Display the equivalent non-interactive command. */
    public static final String OPTION_LONG_DISPLAY_EQUIVALENT = "displayCommand";
    /** The path where we write the equivalent non-interactive command. */
    public static final String OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH = "commandFilePath";
    /** The value for the short option remote . */
    public static final char OPTION_SHORT_REMOTE = 'r';
    /** The value for the long option remote . */
    public static final String OPTION_LONG_REMOTE = "remote";
    /** The value for the short option configClass. */
    public static final char OPTION_SHORT_CONFIG_CLASS = 'C';
    /** The value for the long option configClass. */
    public static final String OPTION_LONG_CONFIG_CLASS = "configClass";
    /** Value for the server root option short form. */
    public static final Character OPTION_SHORT_SERVER_ROOT = 'R';
    /** Value for the server root option long form. */
    public static final String OPTION_LONG_SERVER_ROOT = "serverRoot";
    /** Value for the control option short form. */
    public static final Character OPTION_SHORT_CONTROL = 'J';
    /** Value for the control option long form. */
    public static final String OPTION_LONG_CONTROL = "control";
    /** Recurring task option long form. */
    public static final String OPTION_LONG_RECURRING_TASK = "recurringTask";
    /** Recurring task option short form. */
    public static final Character OPTION_SHORT_RECURRING_TASK = null;
    /** Subentries control option long form. */
    public static final String OPTION_LONG_SUBENTRIES = "subEntries";
    /** Subentries control option short form. */
    public static final Character OPTION_SHORT_SUBENTRIES = null;
    /** Scheduled start date/time option long form. */
    public static final String OPTION_LONG_START_DATETIME = "start";
    /** Scheduled start date/time option short form. */
    public static final Character OPTION_SHORT_START_DATETIME = 't';
    /** Long form of admin password. */
    public static final String OPTION_LONG_ADMIN_PWD = "adminPassword";
    /** Long form of admin password file. */
    public static final String OPTION_LONG_ADMIN_PWD_FILE = "adminPasswordFile";
    /**
     * The name of the SASL property that can be used to provide trace information
     * for a SASL ANONYMOUS request.
     */
    public static final String SASL_PROPERTY_TRACE = "trace";
    /** The value for the long option force upgrade. */
    public static final String OPTION_LONG_FORCE_UPGRADE = "force";
    /** The value for the long option ignore errors. */
    public static final String OPTION_LONG_IGNORE_ERRORS = "ignoreErrors";
    /** Value for the restart option long form. */
    public static final String OPTION_LONG_RESTART = "restart";
    /** The value for the hidden testonly argument. */
    public static final String OPTION_LONG_TESTONLY_ARGUMENT = "testOnly";
    /** The value for the backend type long option. */
    public static final String OPTION_LONG_BACKEND_TYPE = "backendType";
    /** The value for the backend type short option. */
    public static final Character OPTION_SHORT_BACKEND_TYPE = 't';
    /** Prevent instantiation. */
    private ArgumentConstants() {
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentException.java
New file
@@ -0,0 +1,61 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * This class defines an exception that may be thrown if there is a problem with
 * an argument definition.
 */
@SuppressWarnings("serial")
public 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.
     */
    public 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.
     */
    public ArgumentException(final LocalizableMessage message, final Throwable cause) {
        super(String.valueOf(message), cause);
        this.message = message;
    }
    @Override
    public LocalizableMessage getMessageObject() {
        return this.message;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentGroup.java
New file
@@ -0,0 +1,154 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions copyright 2012-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Class for organizing options into logical groups when argument usage is printed. To use an argument group, create an
 * instance and use {@code ArgumentParser#addArgument(Argument, ArgumentGroup)} when adding arguments for to the parser.
 */
public final class ArgumentGroup implements Comparable<ArgumentGroup> {
    /** Description for this group of arguments. */
    private LocalizableMessage description;
    /** List of arguments belonging to this group. */
    private final List<Argument> args = new LinkedList<>();
    /** 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.
     */
    public ArgumentGroup(final LocalizableMessage description, final int priority) {
        this.description = description;
        this.priority = priority;
    }
    @Override
    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
     */
    public boolean addArgument(final Argument arg) {
        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;
                }
            }
            return this.args.add(arg);
        }
        return false;
    }
    /**
     * Indicates whether this group contains any members.
     *
     * @return boolean where true means this group contains members
     */
    boolean containsArguments() {
        return !args.isEmpty();
    }
    /**
     * 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;
    }
    @Override
    public String toString() {
        return getClass().getSimpleName() + "(description=" + description + ")";
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java
New file
@@ -0,0 +1,1678 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2010 Sun Microsystems, Inc.
 * Portions copyright 2012-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.ArgumentConstants.*;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.cli.DocGenerationHelper.*;
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.util.StaticUtils.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.slf4j.LocalizedLogger;
/**
 * 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
 * internationalizable 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.
 */
public class ArgumentParser implements ToolRefDocContainer {
    private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
    private static final Set<String> HOST_LONG_IDENTIFIERS = new HashSet<>(Arrays.asList(
            OPTION_LONG_HOST,
            OPTION_LONG_REFERENCED_HOST_NAME,
            "host1",
            "host2",
            "hostSource",
            "hostDestination"));
    /**
     * The name of the OpenDJ configuration direction in the user home
     * directory.
     */
    public static final String DEFAULT_OPENDJ_CONFIG_DIR = ".opendj";
    /** The default properties file name. */
    public static final String DEFAULT_OPENDJ_PROPERTIES_FILE_NAME = "tools";
    /** The default properties file extension. */
    public static final String DEFAULT_OPENDJ_PROPERTIES_FILE_EXTENSION = ".properties";
    /** The name of a command-line script used to launch a tool. */
    public static final String PROPERTY_SCRIPT_NAME = "com.forgerock.opendj.ldap.tools.scriptName";
    /** The legacy name of a command-line script used to launch a tool. */
    public static final String PROPERTY_SCRIPT_NAME_LEGACY = "org.opends.server.scriptName";
    /** 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 OpenDJ version. */
    private Argument versionArgument;
    /** The set of unnamed trailing arguments that were provided for this parser. */
    private final ArrayList<String> trailingArguments = new ArrayList<>();
    /**
     * 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 handler to call to print the product version. */
    private VersionHandler versionHandler = new VersionHandler() {
        @Override
        public void printVersion() {
            // display nothing at all
        }
        @Override
        public String toString() {
            return "<no version displayed>";
        }
    };
    /** The set of arguments defined for this parser, referenced by short ID. */
    private final Map<Character, Argument> shortIDMap = new HashMap<>();
    /** The set of arguments defined for this parser, referenced by long ID. */
    private final Map<String, Argument> longIDMap = new HashMap<>();
    /** The total set of arguments defined for this parser. */
    private final List<Argument> argumentList = new LinkedList<>();
    /** 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 output stream to which usage information should be printed. */
    private OutputStream usageOutputStream = System.out;
    /**
     * 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;
    /** A short description for this tool, suitable in a man page summary line. */
    private LocalizableMessage shortToolDescription;
    /** The display name that will be used for the trailing arguments in the usage information. */
    private final String trailingArgsDisplayName;
    /** Set of argument groups. */
    protected final Set<ArgumentGroup> argumentGroups = new TreeSet<>();
    /**
     * 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.
     */
    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.
     */
    protected 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 static final String INDENT = "    ";
    /**
     * 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.
     */
    public ArgumentParser(final String mainClassName, final LocalizableMessage toolDescription,
            final boolean longArgumentsCaseSensitive) {
        this.mainClassName = mainClassName;
        this.toolDescription = toolDescription;
        this.longArgumentsCaseSensitive = longArgumentsCaseSensitive;
        allowsTrailingArguments = false;
        trailingArgsDisplayName = null;
        maxTrailingArguments = 0;
        minTrailingArguments = 0;
        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.
     */
    public 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;
        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.
     */
    public 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.
     */
    public void addArgument(final Argument argument, ArgumentGroup group) throws ArgumentException {
        final Character shortID = argument.getShortIdentifier();
        if (shortID != null && shortIDMap.containsKey(shortID)) {
            final String conflictingID = shortIDMap.get(shortID).getLongIdentifier();
            throw new ArgumentException(
                    ERR_ARGPARSER_DUPLICATE_SHORT_ID.get(argument.getLongIdentifier(), shortID, conflictingID));
        }
        // JNR: what is the requirement for the following code?
        if (versionArgument != null
                && shortID != null
                && shortID.equals(versionArgument.getShortIdentifier())) {
            // Update the version argument to not display its short identifier.
            try {
                versionArgument = getVersionArgument(false);
                // JNR: why not call addGeneralArgument(versionArgument) here?
                this.generalArgGroup.addArgument(versionArgument);
            } catch (final ArgumentException e) {
                // ignore
            }
        }
        final String longID = formatLongIdentifier(argument.getLongIdentifier());
        if (longIDMap.containsKey(longID)) {
            throw new ArgumentException(ERR_ARGPARSER_DUPLICATE_LONG_ID.get(argument.getLongIdentifier()));
        }
        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);
    }
    private BooleanArgument getVersionArgument(final boolean displayShortIdentifier) throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_PRODUCT_VERSION)
                .shortIdentifier(displayShortIdentifier ? OPTION_SHORT_PRODUCT_VERSION : null)
                .description(INFO_DESCRIPTION_PRODUCT_VERSION.get())
                .buildArgument();
    }
    /**
     * Adds the provided argument to the set of arguments handled by this parser
     * and puts the argument 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.
     */
    protected 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 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.
     */
    public 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;
        if (filePropertiesPathArgument.isPresent()) {
            propertiesFilePath = filePropertiesPathArgument.getValue();
        } else {
            // Check in "user home"/.opendj directory
            final String userDir = System.getProperty("user.home");
            propertiesFilePath =
                    findPropertiesFile(userDir + File.separator + DEFAULT_OPENDJ_CONFIG_DIR);
        }
        // We don't have a properties file location
        if (propertiesFilePath == null) {
            return null;
        }
        // We have a location for the properties file.
        try {
            final Properties argumentProperties = new Properties();
            final String scriptName = getScriptName();
            final Properties p = new Properties();
            try (final FileInputStream fis = new FileInputStream(propertiesFilePath)) {
                p.load(fis);
            }
            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));
            }
            return argumentProperties;
        } catch (final Exception e) {
            final LocalizableMessage message =
                    ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(propertiesFilePath, getExceptionMessage(e));
            throw new ArgumentException(message, e);
        }
    }
    /**
     * 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.
     */
    public Argument getArgumentForLongID(final String longID) {
        return longIDMap.get(formatLongIdentifier(longID));
    }
    /**
     * 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.
     */
    public List<Argument> getArgumentList() {
        return argumentList;
    }
    /**
     * 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;
    }
    /**
     * 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) {
        if (isInputOutputArgument(argument)) {
            return ioArgGroup;
        } else if (isGeneralArgument(argument)) {
            return generalArgGroup;
        } else if (isLdapConnectionArgument(argument)) {
            return ldapArgGroup;
        } else {
            return defaultArgGroup;
        }
    }
    /**
     * 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;
    }
    @Override
    public LocalizableMessage getShortToolDescription() {
        return shortToolDescription != null ? shortToolDescription : LocalizableMessage.EMPTY;
    }
    @Override
    public void setShortToolDescription(final LocalizableMessage shortDescription) {
        this.shortToolDescription = shortDescription;
    }
    /**
     * A supplement to the description for this tool
     * intended for use in generated reference documentation.
     */
    private DocSubcommandDescriptionSupplement docToolDescriptionSupplement;
    @Override
    public LocalizableMessage getDocToolDescriptionSupplement() {
        this.docToolDescriptionSupplement =
                constructIfNull(this.docToolDescriptionSupplement);
        return this.docToolDescriptionSupplement.getDocDescriptionSupplement();
    }
    @Override
    public void setDocToolDescriptionSupplement(final LocalizableMessage supplement) {
        this.docToolDescriptionSupplement =
                constructIfNull(this.docToolDescriptionSupplement);
        this.docToolDescriptionSupplement.setDocDescriptionSupplement(supplement);
    }
    /**
     * A supplement to the description for all subcommands of this tool,
     * intended for use in generated reference documentation.
     */
    private class DocSubcommandDescriptionSupplement implements DocDescriptionSupplement {
        /** A supplement to the description intended for use in generated reference documentation. */
        private LocalizableMessage docDescriptionSupplement;
        @Override
        public LocalizableMessage getDocDescriptionSupplement() {
            return docDescriptionSupplement != null ? docDescriptionSupplement : LocalizableMessage.EMPTY;
        }
        private void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
            this.docDescriptionSupplement = docDescriptionSupplement;
        }
    }
    private DocSubcommandDescriptionSupplement docSubcommandsDescriptionSupplement;
    @Override
    public LocalizableMessage getDocSubcommandsDescriptionSupplement() {
        this.docSubcommandsDescriptionSupplement =
                constructIfNull(this.docSubcommandsDescriptionSupplement);
        return this.docSubcommandsDescriptionSupplement.getDocDescriptionSupplement();
    }
    @Override
    public void setDocSubcommandsDescriptionSupplement(final LocalizableMessage supplement) {
        this.docSubcommandsDescriptionSupplement =
                constructIfNull(this.docSubcommandsDescriptionSupplement);
        this.docSubcommandsDescriptionSupplement.setDocDescriptionSupplement(supplement);
    }
    private DocSubcommandDescriptionSupplement constructIfNull(DocSubcommandDescriptionSupplement supplement) {
        if (supplement != null) {
            return supplement;
        }
        return new DocSubcommandDescriptionSupplement();
    }
    /**
     * 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.
     */
    public 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.
     */
    public String getUsage() {
        final StringBuilder buffer = new StringBuilder();
        usageOrVersionDisplayed = true;
        if (System.getProperty("org.forgerock.opendj.gendoc") != null) {
            toRefEntry(buffer, getSynopsisArgs(), argumentList);
        } else {
            getUsage(buffer);
        }
        return buffer.toString();
    }
    /**
     * Return the list of arguments for the generated reference documentation.
     *
     * @return  The list of arguments for the generated reference documentation.
     */
    String getSynopsisArgs() {
        if (allowsTrailingArguments()) {
            if (trailingArgsDisplayName != null) {
                return trailingArgsDisplayName;
            } else {
                return INFO_ARGPARSER_USAGE_TRAILINGARGS.get().toString();
            }
        }
        return null;
    }
    /**
     * Appends a generated DocBook XML RefEntry (man page) to the StringBuilder.
     *
     * @param builder       Append the RefEntry element to this.
     * @param synopsisArgs  List of arguments for the command synopsis.
     * @param argList       List of (global) arguments for this tool.
     */
    void toRefEntry(StringBuilder builder, String synopsisArgs, List<Argument> argList) {
        final String scriptName = getScriptName();
        if (scriptName == null) {
            throw new RuntimeException("The script name should have been set via the environment property '"
                    + PROPERTY_SCRIPT_NAME + "'.");
        }
        final Map<String, Object> map = new HashMap<>();
        map.put("locale", Locale.getDefault().getLanguage());
        map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
        map.put("name", scriptName);
        map.put("shortDesc", getShortToolDescription());
        map.put("descTitle", REF_TITLE_DESCRIPTION.get());
        map.put("args", synopsisArgs);
        map.put("description", eolToNewPara(getToolDescription()));
        map.put("info", getDocToolDescriptionSupplement());
        if (!argList.isEmpty()) {
            map.put("optionSection", getOptionsRefSect1(scriptName));
        }
        map.put("subcommands", null);
        map.put("trailingSectionString", System.getProperty("org.forgerock.opendj.gendoc.trailing"));
        applyTemplate(builder, "refEntry.ftl", map);
    }
    /**
     * Returns a String with line separators replaced by {@code &lt;/para>&lt;para>}.
     * @param input String in which to replace line separators.
     * @return A String with line separators replaced by {@code &lt;/para>&lt;para>}.
     */
    String eolToNewPara(final LocalizableMessage input) {
        return input.toString().replaceAll(EOL, "</para><para>");
    }
    /**
     * Returns a generated DocBook XML RefSect1 element for all command options.
     * @param scriptName    The name of this script.
     * @return              The RefSect1 element as a String.
     */
    protected String getOptionsRefSect1(String scriptName) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", scriptName);
        map.put("title", REF_TITLE_OPTIONS.get());
        map.put("intro", REF_INTRO_OPTIONS.get(scriptName));
        Argument helpArgument = null;
        final boolean printHeaders = printUsageGroupHeaders();
        List<Map<String, Object>> groups = new LinkedList<>();
        for (final ArgumentGroup argGroup : argumentGroups) {
            Map<String, Object> group = new HashMap<>();
            // Add the group's description if any
            if (argGroup.containsArguments() && printHeaders) {
                LocalizableMessage description = argGroup.getDescription();
                if (description != LocalizableMessage.EMPTY) {
                    group.put("description", eolToNewPara(description));
                } else {
                    group.put("description", INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get());
                }
            }
            List<Map<String, Object>> options = new LinkedList<>();
            final SortedSet<Argument> args = sortArguments(argGroup.getArguments());
            for (final Argument a : args) {
                if (a.isHidden()) {
                    continue;
                }
                final Map<String, Object> argumentMap = getArgumentMap(a);
                // Return a generic FQDN for localhost as the default hostname in reference documentation.
                if (isHostNameArgument(a)) {
                    argumentMap.put("default", REF_DEFAULT.get("localhost.localdomain"));
                }
                // Return a generic message as default backend type depends on the server distribution.
                if (a.getLongIdentifier().equals(OPTION_LONG_BACKEND_TYPE)) {
                    argumentMap.put("default", REF_DEFAULT_BACKEND_TYPE.get().toString());
                }
                // The help argument should be added at the end.
                if (isUsageArgument(a)) {
                    helpArgument = a;
                    continue;
                }
                options.add(argumentMap);
            }
            group.put("options", options);
            if (!options.isEmpty()) {
                groups.add(group);
            }
        }
        if (helpArgument != null) {
            Map<String, Object> helpGroup = new HashMap<>();
            helpGroup.put("description", null);
            List<Map<String, Object>> options = new LinkedList<>();
            options.add(getArgumentMap(helpArgument));
            helpGroup.put("options", options);
            groups.add(helpGroup);
        }
        map.put("groups", groups);
        StringBuilder sb = new StringBuilder();
        applyTemplate(sb, "optionsRefSect1.ftl", map);
        return sb.toString();
    }
    /**
     * Returns true if this argument is for setting a hostname.
     * @param a The argument.
     * @return true if this argument is for setting a hostname.
     */
    boolean isHostNameArgument(final Argument a) {
        return HOST_LONG_IDENTIFIERS.contains(a.getLongIdentifier());
    }
    /**
     * Returns a map containing information about an argument option.
     * @param   a   The argument
     * @return      A map containing information about an argument option
     */
    private Map<String, Object> getArgumentMap(final Argument a) {
        Map<String, Object> option = new HashMap<>();
        option.put("synopsis", getOptionSynopsis(a));
        option.put("description", eolToNewPara(a.getDescription()));
        String dv = a.getDefaultValue();
        option.put("default", dv != null ? REF_DEFAULT.get(dv) : null);
        option.put("info", a.getDocDescriptionSupplement());
        return option;
    }
    /**
     * Writes message to the usage output stream.
     *
     * @param message the message to write
     */
    void writeToUsageOutputStream(CharSequence message) {
        try {
            usageOutputStream.write(getBytes(message.toString()));
        } catch (final Exception e) {
            logger.traceException(e);
        }
    }
    /**
     * Appends usage information based on the defined arguments to the provided
     * buffer.
     *
     * @param buffer
     *            The buffer to which the usage information should be appended.
     */
    private void getUsage(final StringBuilder buffer) {
        buffer.append(getLocalizableScriptName());
        if (allowsTrailingArguments) {
            buffer.append(" ");
            if (trailingArgsDisplayName != null) {
                buffer.append(trailingArgsDisplayName);
            } else {
                buffer.append(INFO_ARGPARSER_USAGE_TRAILINGARGS.get());
            }
        }
        buffer.append(EOL);
        buffer.append(EOL);
        if (toolDescription != null && toolDescription.length() > 0) {
            buffer.append(wrapText(toolDescription.toString(), MAX_LINE_WIDTH - 1));
            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_LINE_WIDTH - 1));
                    buffer.append(EOL);
                    buffer.append(EOL);
                }
            }
            final SortedSet<Argument> args = sortArguments(argGroup.getArguments());
            for (final Argument a : args) {
                if (a.isHidden()) {
                    continue;
                }
                // Help argument should be printed at the end
                if (isUsageArgument(a)) {
                    helpArgument = a;
                    continue;
                }
                printArgumentUsage(a, buffer);
            }
        }
        if (helpArgument != null) {
            printArgumentUsage(helpArgument, buffer);
        } else {
            buffer.append(EOL);
            buffer.append("-?");
            buffer.append(EOL);
        }
    }
    /**
     * Sorts arguments by identifier, lowercase options first then uppercase.
     *
     * @param arguments     The arguments to sort.
     * @return              The set of arguments in sorted order.
     */
    SortedSet<Argument> sortArguments(final List<Argument> arguments) {
        final SortedSet<Argument> result = new TreeSet<>(new Comparator<Argument>() {
            @Override
            public int compare(final Argument o1, final Argument o2) {
                final String s1 = getIdentifier(o1);
                final String s2 = getIdentifier(o2);
                final int res = s1.compareToIgnoreCase(s2);
                if (res != 0) {
                    return res;
                }
                // Lowercase options first then uppercase.
                return -s1.compareTo(s2);
            }
            private String getIdentifier(final Argument o1) {
                if (o1.getShortIdentifier() != null) {
                    return o1.getShortIdentifier().toString();
                }
                return o1.getLongIdentifier();
            }
        });
        result.addAll(arguments);
        return result;
    }
    /**
     * Returns the script name or a Java equivalent command-line string.
     *
     * @return the script name or a Java equivalent command-line string
     */
    String getScriptNameOrJava() {
        final String scriptName = getScriptName();
        if (scriptName != null && scriptName.length() != 0) {
            return scriptName;
        }
        return "java " + getMainClassName();
    }
    /**
     * Returns the script name as a {@link LocalizableMessage}.
     *
     * @return the script name as a {@link LocalizableMessage}
     */
    LocalizableMessage getLocalizableScriptName() {
        final String scriptName = getScriptName();
        if (scriptName == null || scriptName.length() == 0) {
            return INFO_ARGPARSER_USAGE_JAVA_CLASSNAME.get(mainClassName);
        }
        return INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME.get(scriptName);
    }
    /**
     * Returns the script name if set.
     *
     * @return the script name, or {@code null} if not set
     */
    String getScriptName() {
        final String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME);
        if (scriptName != null && scriptName.length() != 0) {
            return scriptName;
        }
        final String legacyScriptName = System.getProperty(PROPERTY_SCRIPT_NAME_LEGACY);
        if (legacyScriptName != null && legacyScriptName.length() != 0) {
            return legacyScriptName;
        }
        return null;
    }
    /**
     * Returns the usage argument.
     *
     * @return the usageArgument
     */
    Argument getUsageArgument() {
        return usageArgument;
    }
    /**
     * Returns whether the provided argument is the usage argument.
     *
     * @param a the argument to test
     * @return true if the provided argument is the usage argument, false otherwise
     */
    boolean isUsageArgument(final Argument a) {
        return usageArgument != null && usageArgument.getLongIdentifier().equals(a.getLongIdentifier());
    }
    /** Prints the version. */
    void printVersion() {
        versionPresent = true;
        usageOrVersionDisplayed = true;
        versionHandler.printVersion();
    }
    /**
     * 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.
     */
    public boolean isUsageArgumentPresent() {
        return usageArgument != null && usageArgument.isPresent();
    }
    /**
     * 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.
     */
    public boolean isVersionArgumentPresent() {
        return versionPresent;
    }
    /**
     * Indicates whether subcommand names and long argument strings should be treated in a case-sensitive manner.
     *
     * @return <CODE>true</CODE> if subcommand names and long argument strings should be treated in a case-sensitive
     *         manner, or <CODE>false</CODE> if they should not.
     */
    boolean longArgumentsCaseSensitive() {
        return longArgumentsCaseSensitive;
    }
    /**
     * 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.
     */
    public 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.
     */
    public void parseArguments(final String[] rawArguments, Properties argumentProperties) throws ArgumentException {
        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 equalsPos < 0, this is fine. The value is not part of the argument name token.
                if (equalPos == 0) {
                    // The argument starts with "--=", which is not acceptable.
                    throw new ArgumentException(ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME.get(arg));
                } else if (equalPos > 0) {
                    // 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;
                argName = formatLongIdentifier(argName);
                // Get the argument with the specified name.
                final Argument a = longIDMap.get(argName);
                if (a == null) {
                    if (OPTION_LONG_HELP.equals(argName)) {
                        // "--help" will always be interpreted as requesting usage information.
                        writeToUsageOutputStream(getUsage());
                        return;
                    } else if (OPTION_LONG_PRODUCT_VERSION.equals(argName)) {
                        // "--version" will always be interpreted as requesting version information.
                        printVersion();
                        return;
                    } else {
                        // There is no such argument registered.
                        throw new ArgumentException(
                                ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID.get(origArgName));
                    }
                } else {
                    a.setPresent(true);
                    // If this is the usage argument, then immediately stop and
                    // print usage information.
                    if (isUsageArgument(a)) {
                        writeToUsageOutputStream(getUsage());
                        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) {
                            throw new ArgumentException(
                                    ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get(origArgName));
                        }
                        argValue = rawArguments[++i];
                    }
                    final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
                    if (!a.valueIsAcceptable(argValue, invalidReason)) {
                        throw new ArgumentException(
                                ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID.get(argValue,
                                        origArgName, invalidReason));
                    }
                    // If the argument already has a value, then make sure it is
                    // acceptable to have more than one.
                    if (a.hasValue() && !a.isMultiValued()) {
                        throw new ArgumentException(ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID.get(origArgName));
                    }
                    a.addValue(argValue);
                } else if (argValue != null) {
                    throw new ArgumentException(
                            ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE.get(origArgName));
                }
            } 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("-")) {
                    throw new ArgumentException(ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT.get());
                }
                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 == '?') {
                        writeToUsageOutputStream(getUsage());
                        return;
                    } else if (versionHandler != null && argCharacter == OPTION_SHORT_PRODUCT_VERSION
                            && !shortIDMap.containsKey(OPTION_SHORT_PRODUCT_VERSION)) {
                        printVersion();
                        return;
                    } else {
                        // There is no such argument registered.
                        throw new ArgumentException(ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get(argCharacter));
                    }
                } else {
                    a.setPresent(true);
                    // If this is the usage argument, then immediately stop and
                    // print usage information.
                    if (isUsageArgument(a)) {
                        writeToUsageOutputStream(getUsage());
                        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) {
                            throw new ArgumentException(
                                    ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID.get(argCharacter));
                        }
                        argValue = rawArguments[++i];
                    }
                    final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
                    if (!a.valueIsAcceptable(argValue, invalidReason)) {
                        throw new ArgumentException(ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID.get(
                                argValue, argCharacter, invalidReason));
                    }
                    // If the argument already has a value, then make sure it is
                    // acceptable to have more than one.
                    if (a.hasValue() && !a.isMultiValued()) {
                        throw new ArgumentException(ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get(argCharacter));
                    }
                    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.
                            throw new ArgumentException(
                                    ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get(argCharacter));
                        } 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.
                            throw new ArgumentException(
                                    ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES.get(argCharacter, argValue, c));
                        } else {
                            b.setPresent(true);
                            // If this is the usage argument,
                            // then immediately stop and print usage information.
                            if (isUsageArgument(b)) {
                                writeToUsageOutputStream(getUsage());
                                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.
                throw new ArgumentException(ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg));
            }
        }
        // If we allow trailing arguments and there is a minimum number,
        // then make sure at least that many were provided.
        if (allowsTrailingArguments
                && minTrailingArguments > 0
                && trailingArguments.size() < minTrailingArguments) {
            throw new ArgumentException(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(minTrailingArguments));
        }
        // 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.
        normalizeArguments(argumentProperties, argumentList);
    }
    /**
     * 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.
     */
    public void parseArguments(final String[] rawArguments, final String propertiesFile,
            final boolean requirePropertiesFile) throws ArgumentException {
        Properties argumentProperties = null;
        try (final FileInputStream fis = new FileInputStream(propertiesFile)) {
            final Properties p = new Properties();
            p.load(fis);
            argumentProperties = p;
        } catch (final Exception e) {
            if (requirePropertiesFile) {
                final LocalizableMessage message =
                        ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(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 provided argument which will be used to identify the file
     * properties.
     *
     * @param argument
     *            The argument which will be used to identify the file
     *            properties.
     */
    public void setFilePropertiesArgument(final StringArgument argument) {
        filePropertiesPathArgument = argument;
    }
    /**
     * 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.
     */
    public 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.
     */
    public 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.
     */
    public void setUsageArgument(final Argument argument, final OutputStream outputStream) {
        usageArgument = argument;
        usageOutputStream = outputStream;
    }
    /**
     * Sets whether the usage or version displayed.
     *
     * @param usageOrVersionDisplayed the usageOrVersionDisplayed to set
     */
    public void setUsageOrVersionDisplayed(boolean usageOrVersionDisplayed) {
        this.usageOrVersionDisplayed = usageOrVersionDisplayed;
    }
    /**
     * Sets the version handler which will be used to display the product version.
     *
     * @param handler
     *            The version handler.
     */
    public void setVersionHandler(final VersionHandler handler) {
        versionHandler = handler;
    }
    /**
     * 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.
     */
    public 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_OPENDJ_PROPERTIES_FILE_NAME
                        + DEFAULT_OPENDJ_PROPERTIES_FILE_EXTENSION);
        if (f.exists() && f.canRead()) {
            return f.getAbsolutePath();
        }
        return null;
    }
    private void initGroups() {
        this.argumentGroups.add(defaultArgGroup);
        this.argumentGroups.add(ldapArgGroup);
        this.argumentGroups.add(generalArgGroup);
        this.argumentGroups.add(ioArgGroup);
        try {
            versionArgument = getVersionArgument(true);
            // JNR: why not call addGeneralArgument(versionArgument) here?
            this.generalArgGroup.addArgument(versionArgument);
        } catch (final ArgumentException e) {
            // ignore
        }
    }
    private boolean isGeneralArgument(final Argument arg) {
        if (arg != null) {
            final String longId = arg.getLongIdentifier();
            return OPTION_LONG_HELP.equals(longId) || OPTION_LONG_PRODUCT_VERSION.equals(longId);
        }
        return false;
    }
    private boolean isInputOutputArgument(final Argument arg) {
        if (arg != null) {
            final String longId = arg.getLongIdentifier();
            return 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 false;
    }
    private boolean isLdapConnectionArgument(final Argument arg) {
        if (arg != null) {
            final String longId = arg.getLongIdentifier();
            return 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 false;
    }
    /**
     * 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) {
        printLineForShortLongArgument(a, buffer);
        // 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.
        final int indentLength = INDENT.length();
        buffer.append(wrapText(a.getDescription(), MAX_LINE_WIDTH, 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()));
            buffer.append(EOL);
        }
    }
    /**
     * Appends a line with the short and/or long identifiers that may be used for the argument to the provided string
     * builder.
     *
     * @param a the argument for which to print a line
     * @param buffer the string builder where to append the line
     */
    void printLineForShortLongArgument(final Argument a, final StringBuilder buffer) {
        final Character shortID = a.getShortIdentifier();
        final String longID = a.getLongIdentifier();
        if (shortID != null) {
            if (isUsageArgument(a)) {
                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 currentLength = buffer.length();
                final int lineLength = (buffer.length() - currentLength) + newBuffer.length();
                if (lineLength > MAX_LINE_WIDTH) {
                    buffer.append(EOL);
                }
                buffer.append(newBuffer);
            }
            buffer.append(EOL);
        } else if (longID != null) {
            if (isUsageArgument(a)) {
                buffer.append("-?, ");
            }
            buffer.append("--");
            buffer.append(longID);
            if (a.needsValue()) {
                buffer.append(" ");
                buffer.append(a.getValuePlaceholder());
            }
            buffer.append(EOL);
        }
    }
    void normalizeArguments(final Properties argumentProperties, final List<Argument> arguments)
            throws ArgumentException {
        for (final Argument a : arguments) {
            // See if there is a value in the properties that can be used
            if (!a.isPresent() && argumentProperties != null) {
                final String value = argumentProperties.getProperty(a.getLongIdentifier().toLowerCase());
                final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
                if (value != null) {
                    boolean addValue = (a instanceof BooleanArgument) || a.valueIsAcceptable(value, invalidReason);
                    if (addValue) {
                        a.addValue(value);
                        if (a.needsValue()) {
                            a.setPresent(true);
                        }
                        a.valueSetByProperty();
                    }
                }
            }
            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()) {
                    throw new ArgumentException(ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG.get(a.getLongIdentifier()));
                }
            }
        }
    }
    /**
     * Displays the provided message on the provided stream followed by a help usage reference.
     *
     * @param printStream
     *            The stream to print error message and help reference message.
     * @param message
     *            The error message to print.
     */
    public void displayMessageAndUsageReference(final PrintStream printStream, final LocalizableMessage message) {
        printWrappedText(printStream, message);
        printStream.println();
        printWrappedText(printStream, getHelpUsageReference());
    }
    /**
     * Retrieves a string describing how the user can get more help.
     *
     * @return A string describing how the user can get more help.
     */
    public LocalizableMessage getHelpUsageReference() {
        setUsageOrVersionDisplayed(true);
        LocalizableMessageBuilder buffer = new LocalizableMessageBuilder();
        buffer.append(INFO_GLOBAL_HELP_REFERENCE.get(getScriptNameOrJava()));
        buffer.append(EOL);
        return buffer.toMessage();
    }
    /**
     * Get the password which has to be used for the command without prompting the user. If no password was specified,
     * return null.
     *
     * @param clearArg
     *            The password StringArgument argument.
     * @param fileArg
     *            The password FileBased argument.
     * @return The password stored into the specified file on by the command line argument, or null it if not specified.
     */
    public static String getBindPassword(StringArgument clearArg, FileBasedArgument fileArg) {
        if (clearArg.isPresent()) {
            return clearArg.getValue();
        } else if (fileArg.isPresent()) {
            return fileArg.getValue();
        }
        return null;
    }
    /**
     * Replace the provided {@link Argument} from this parser by the provided {@link Argument}.
     * If the {@link Argument} is not present in this parser, do nothing.
     *
     * @param argument
     *          The {@link Argument} to replace.
     */
    public void replaceArgument(final Argument argument) {
        replaceArgumentInCollections(longIDMap, shortIDMap, argumentList, argument);
    }
    void replaceArgumentInCollections(final Map<String, Argument> longIDToArg,
            final Map<Character, Argument> shortIDToArg, final List<Argument> argumentList, final Argument argument) {
        final String longID = formatLongIdentifier(argument.getLongIdentifier());
        if (!longIDToArg.containsKey(longID)) {
            return;
        }
        longIDToArg.put(longID, argument);
        shortIDToArg.put(argument.getShortIdentifier(), argument);
        argumentList.remove(argument);
        argumentList.add(argument);
        for (final ArgumentGroup group : argumentGroups) {
            if (group.getArguments().contains(argument)) {
                group.removeArgument(argument);
                group.addArgument(argument);
            }
        }
    }
    String formatLongIdentifier(final String longIdentifier) {
        return longArgumentsCaseSensitive ? longIdentifier : toLowerCase(longIdentifier);
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/BooleanArgument.java
New file
@@ -0,0 +1,89 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.ERR_BOOLEANARG_NO_VALUE_ALLOWED;
import org.forgerock.i18n.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".
 */
public final class BooleanArgument extends Argument {
    /**
     * Returns a builder which can be used for incrementally constructing a new
     * {@link BooleanArgument}.
     *
     * @param longIdentifier
     *         The long identifier that will be used to refer to this argument.
     * @return A builder to continue building the {@link BooleanArgument}.
     */
    public static Builder builder(final String longIdentifier) {
        return new Builder(longIdentifier);
    }
    /** A fluent API for incrementally constructing {@link BooleanArgument}. */
    public static final class Builder extends ArgumentBuilder<Builder, Boolean, BooleanArgument> {
        private Builder(final String longIdentifier) {
            super(longIdentifier);
            this.needsValue = false;
            this.defaultValue = false;
        }
        @Override
        Builder getThis() {
            return this;
        }
        @Override
        public BooleanArgument buildArgument() throws ArgumentException {
            return new BooleanArgument(this);
        }
    }
    private BooleanArgument(final Builder builder) throws ArgumentException {
        super(builder);
    }
    @Override
    public final void addValue(final String valueString) {
        if (valueString != null) {
            clearValues();
            super.addValue(valueString);
            super.setPresent(Boolean.valueOf(valueString));
        }
    }
    @Override
    public final void setPresent(final boolean isPresent) {
        addValue(String.valueOf(isPresent));
    }
    @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(longIdentifier));
        return false;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CliConstants.java
New file
@@ -0,0 +1,69 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2010 Sun Microsystems, Inc.
 * Portions copyright 2012-2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * This class defines a number of constants used by tools.
 */
public final class CliConstants {
    /** The minimum java specification supported string version. */
    public static final float MINIMUM_JAVA_VERSION = 1.7F;
    /** Default value for LDAP connection timeout. */
    public static final int DEFAULT_LDAP_CONNECT_TIMEOUT = 30000;
    /** Default value for incrementing port number. */
    public static final int PORT_INCREMENT = 1000;
    /** Default port number for the LDAP port. */
    public static final int DEFAULT_LDAP_PORT = 389;
    /** Default port number for the LDAPS port. */
    public static final int DEFAULT_LDAPS_PORT = 1636;
    /** Default port number for the administrator port. */
    public static final int DEFAULT_ADMIN_PORT = 1444;
    /** Default port number for the SSL Connection. */
    public static final int DEFAULT_SSL_PORT = 636;
    /** Default port number for the JMX Connection handler. */
    public static final int DEFAULT_JMX_PORT = 1689;
    /** Default port number for the HTTP Connection handler. */
    public static final int DEFAULT_HTTP_PORT = 8080;
    /** Default port number for the SNMP Connection handler. */
    public static final int DEFAULT_SNMP_PORT = 161;
    /** Default name of root user DN. */
    public static final String DEFAULT_ROOT_USER_DN = "cn=Directory Manager";
    /** Default Administration Connector port. */
    public static final int DEFAULT_ADMINISTRATION_CONNECTOR_PORT = 4444;
    /** Default Administration UID. */
    public static final String GLOBAL_ADMIN_UID = "admin";
    /** Prevent instantiation. */
    private CliConstants() {
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ClientException.java
New file
@@ -0,0 +1,98 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.ERR_CONSOLE_INPUT_ERROR;
import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * This class defines an exception that may be thrown if a local problem occurs in a Directory Server client.
 */
public class ClientException extends Exception implements LocalizableException {
    /**
     * The serial version identifier required to satisfy the compiler because this class extends
     * <CODE>java.lang.Exception</CODE>, which implements the <CODE>java.io.Serializable</CODE> interface. This value
     * was generated using the <CODE>serialver</CODE> command-line utility included with the Java SDK.
     */
    private static final long serialVersionUID = 1384120263337669664L;
    /** The return code. */
    private ReturnCode returnCode;
    /** The message linked to that exception. */
    private final LocalizableMessage message;
    /**
     * 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.
     */
    public static ClientException adaptInputException(final Throwable cause) {
        return new ClientException(ReturnCode.ERROR_USER_DATA, ERR_CONSOLE_INPUT_ERROR.get(cause.getMessage()), cause);
    }
    /**
     * Creates a new client exception with the provided message.
     *
     * @param exitCode
     *            The exit code that may be used if the client considers this to be a fatal problem.
     * @param message
     *            The message that explains the problem that occurred.
     */
    public ClientException(ReturnCode exitCode, LocalizableMessage message) {
        super(message.toString());
        this.returnCode = exitCode;
        this.message = message;
    }
    /**
     * Creates a new client exception with the provided message and root cause.
     *
     * @param exitCode
     *            The exit code that may be used if the client considers this to be a fatal problem.
     * @param message
     *            The message that explains the problem that occurred.
     * @param cause
     *            The exception that was caught to trigger this exception.
     */
    public ClientException(ReturnCode exitCode, LocalizableMessage message, Throwable cause) {
        super(message.toString(), cause);
        this.returnCode = exitCode;
        this.message = message;
    }
    /**
     * Retrieves the exit code that the client may use if it considers this to be a fatal problem.
     *
     * @return The exit code that the client may use if it considers this to be a fatal problem.
     */
    public int getReturnCode() {
        return returnCode.get();
    }
    @Override
    public LocalizableMessage getMessageObject() {
        return message;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CommandBuilder.java
New file
@@ -0,0 +1,275 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008-2009 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.Utils.OBFUSCATED_VALUE;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.forgerock.opendj.util.OperatingSystem;
/**
 * Class used to be able to generate the non interactive mode.
 */
public class CommandBuilder {
    private String commandName;
    private String subcommandName;
    private final ArrayList<Argument> args = new ArrayList<>();
    private final HashSet<Argument> obfuscatedArgs = new HashSet<>();
    /**
     * The separator used to link the lines of the resulting command-lines.
     */
    public static final String LINE_SEPARATOR;
    static {
        if (OperatingSystem.isWindows()) {
            LINE_SEPARATOR = " ";
        } else {
            LINE_SEPARATOR = " \\\n          ";
        }
    }
    /**
     * The separator used to link the lines of the resulting command-lines in HTML format.
     */
    public static final String HTML_LINE_SEPARATOR;
    static {
        if (OperatingSystem.isWindows()) {
            HTML_LINE_SEPARATOR = "&nbsp;";
        } else {
            HTML_LINE_SEPARATOR = "&nbsp;\\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        }
    }
    /** Creates a {@link CommandBuilder} with {@code null} command and subcommand names. */
    public CommandBuilder() {
        this(null, null);
    }
    /**
     * The constructor for the CommandBuilder.
     *
     * @param commandName
     *            The command name.
     * @param subcommandName
     *            The sub command name.
     */
    public CommandBuilder(String commandName, String subcommandName) {
        this.commandName = commandName;
        this.subcommandName = subcommandName;
    }
    /**
     * Adds an argument to the list of the command builder.
     *
     * @param argument
     *            The argument to be added.
     */
    public void addArgument(final Argument argument) {
        // We use an ArrayList to be able to provide the possibility of updating
        // the position of the attributes.
        if (!args.contains(argument)) {
            args.add(argument);
        }
    }
    /**
     * Adds an argument whose values must be obfuscated (passwords for instance).
     *
     * @param argument
     *            The argument to be added.
     */
    public void addObfuscatedArgument(final Argument argument) {
        addArgument(argument);
        obfuscatedArgs.add(argument);
    }
    /**
     * Removes the provided argument from this CommandBuilder.
     *
     * @param argument
     *            The argument to be removed.
     * @return <CODE>true</CODE> if the attribute was present and removed and <CODE>false</CODE> otherwise.
     */
    public boolean removeArgument(final Argument argument) {
        obfuscatedArgs.remove(argument);
        return args.remove(argument);
    }
    /**
     * Removes the provided arguments from this CommandBuilder.
     * Arguments which are not in this {@link CommandBuilder} will be ignored.
     *
     * @param arguments
     *            Arguments to be removed.
     */
    public void removeArguments(final Argument... arguments) {
        for (final Argument argument : arguments) {
            removeArgument(argument);
        }
    }
    /**
     * Appends the arguments of another command builder to this command builder.
     *
     * @param builder
     *            The CommandBuilder to append.
     */
    public void append(final CommandBuilder builder) {
        for (final Argument arg : builder.args) {
            if (builder.isObfuscated(arg)) {
                addObfuscatedArgument(arg);
            } else {
                addArgument(arg);
            }
        }
    }
    /**
     * Returns the String representation of this command builder (i.e. what we want to show to the user).
     *
     * @return The String representation of this command builder (i.e. what we want to show to the user).
     */
    @Override
    public String toString() {
        return toString(false, LINE_SEPARATOR);
    }
    /**
     * Returns the String representation of this command builder (i.e. what we want to show to the user).
     *
     * @param lineSeparator
     *            The String to be used to separate lines of the command-builder.
     * @return The String representation of this command builder (i.e. what we want to show to the user).
     */
    public String toString(final String lineSeparator) {
        return toString(false, lineSeparator);
    }
    /**
     * Returns the String representation of this command builder (i.e. what we want to show to the user).
     *
     * @param showObfuscated
     *            Displays in clear the obfuscated values.
     * @param lineSeparator
     *            The String to be used to separate lines of the command-builder.
     * @return The String representation of this command builder (i.e. what we want to show to the user).
     */
    private String toString(final boolean showObfuscated, final String lineSeparator) {
        final StringBuilder builder = new StringBuilder();
        builder.append(commandName);
        if (subcommandName != null) {
            builder.append(" ").append(subcommandName);
        }
        for (final Argument arg : args) {
            // This CLI is always using SSL, and the argument has been removed from
            // the user interface
            if (ArgumentConstants.OPTION_LONG_USE_SSL.equals(arg.getLongIdentifier())) {
                continue;
            }
            String argName;
            if (arg.getLongIdentifier() != null) {
                argName = "--" + arg.getLongIdentifier();
            } else {
                argName = "-" + arg.getShortIdentifier();
            }
            if (arg instanceof BooleanArgument) {
                builder.append(lineSeparator).append(argName);
            } else if (arg instanceof FileBasedArgument) {
                for (String value : ((FileBasedArgument) arg).getNameToValueMap().keySet()) {
                    builder.append(lineSeparator).append(argName).append(" ");
                    builder.append(getOutputValue(value, arg, showObfuscated));
                }
            } else {
                for (String value : arg.getValues()) {
                    builder.append(lineSeparator).append(argName).append(" ");
                    builder.append(getOutputValue(value, arg, showObfuscated));
                }
            }
        }
        return builder.toString();
    }
    private String getOutputValue(final String value, final Argument arg, final boolean showObfuscated) {
        if (isObfuscated(arg) && !showObfuscated) {
            return OBFUSCATED_VALUE;
        }
        return escapeValue(value);
    }
    /**
     * Clears the arguments.
     */
    public void clearArguments() {
        args.clear();
        obfuscatedArgs.clear();
    }
    /**
     * Returns the list of arguments.
     *
     * @return The list of arguments.
     */
    public List<Argument> getArguments() {
        return args;
    }
    /**
     * Tells whether the provided argument's values must be obfuscated or not.
     *
     * @param argument
     *            The argument to handle.
     * @return <CODE>true</CODE> if the attribute's values must be obfuscated and <CODE>false</CODE> otherwise.
     */
    public boolean isObfuscated(final Argument argument) {
        return obfuscatedArgs.contains(argument);
    }
    /** Chars that require special treatment when passing them to command-line. */
    private static final Set<Character> CHARSTOESCAPE = new TreeSet<>(Arrays.asList(
        ' ', '\t', '\n', '|', ';', '<', '>', '(', ')', '$', '`', '\\', '"', '\''));
    /**
     * This method simply takes a value and tries to transform it (with escape or '"') characters so that it can be used
     * in a command line.
     *
     * @param value
     *            The String to be treated.
     * @return The transformed value.
     */
    public static String escapeValue(String value) {
        final StringBuilder b = new StringBuilder();
        if (OperatingSystem.isUnix()) {
            for (int i = 0; i < value.length(); i++) {
                final char c = value.charAt(i);
                if (CHARSTOESCAPE.contains(c)) {
                    b.append('\\');
                }
                b.append(c);
            }
        } else {
            b.append('"').append(value).append('"');
        }
        return b.toString();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/CommonArguments.java
New file
@@ -0,0 +1,1138 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.cli.ArgumentConstants.*;
import static com.forgerock.opendj.cli.CliConstants.DEFAULT_LDAP_CONNECT_TIMEOUT;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.SearchScope;
/**
 * This class regroup commons arguments used by the different CLI.
 */
public final class CommonArguments {
    /** Prevent instantiation. */
    private CommonArguments() {
        // Nothing to do.
    }
    /**
     * Returns the "show usage / help" boolean argument.
     *
     * @return The "show usage" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument showUsageArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_HELP)
                .shortIdentifier(OPTION_SHORT_HELP)
                .description(INFO_DESCRIPTION_SHOWUSAGE.get())
                .buildArgument();
    }
    /**
     * Returns the "verbose" boolean argument.
     *
     * @return The "verbose" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument verboseArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_VERBOSE)
                .shortIdentifier(OPTION_SHORT_VERBOSE)
                .description(INFO_DESCRIPTION_VERBOSE.get())
                .buildArgument();
    }
    /**
     * Returns the "port" integer argument. <br>
     * <i> N.B : the 'p' short option is also used by skipdecode(DBTest),
     * propertiesFile(JavaPropertiesToolArguments).</i>
     *
     * @param defaultPort
     *            The default port number.
     * @param description
     *            Port number's description.
     * @return The "port" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument portArgument(final int defaultPort, final LocalizableMessage description)
            throws ArgumentException {
        return IntegerArgument.builder(OPTION_LONG_PORT)
                .shortIdentifier(OPTION_SHORT_PORT)
                .description(description != null ? description : INFO_DESCRIPTION_ADMIN_PORT.get())
                .range(1, 65535)
                .defaultValue(defaultPort)
                .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "propertiesFilePath" string argument.
     *
     * @return The "propertiesFilePath" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument propertiesFileArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_PROP_FILE_PATH)
                .description(INFO_DESCRIPTION_PROP_FILE_PATH.get())
                .valuePlaceholder(INFO_PROP_FILE_PATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "proxyauthzid" string argument.
     *
     * @return The "proxyauthzid" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument proxyAuthIdArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_PROXYAUTHID)
                .shortIdentifier(OPTION_SHORT_PROXYAUTHID)
                .description(INFO_DESCRIPTION_PROXYAUTHZID.get())
                .valuePlaceholder(INFO_PROXYAUTHID_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "No properties file" boolean argument.
     *
     * @return The "noPropertiesFile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument noPropertiesFileArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_NO_PROP_FILE)
                .description(INFO_DESCRIPTION_NO_PROP_FILE.get())
                .buildArgument();
    }
    /**
     * Returns the "Continue On Error" boolean argument. <br>
     * <i> N.B : the 'c' short option is also used by cleanupservice, compress.</i>
     *
     * @return The "continueOnError" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument continueOnErrorArgument() throws ArgumentException {
        return BooleanArgument.builder("continueOnError")
                .shortIdentifier('c')
                .description(INFO_DESCRIPTION_CONTINUE_ON_ERROR.get())
                .buildArgument();
    }
    /**
     * Returns the "control" string argument.
     *
     * @return The "control" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument controlArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_CONTROL)
                .shortIdentifier(OPTION_SHORT_CONTROL)
                .description(INFO_DESCRIPTION_CONTROLS.get())
                .docDescriptionSupplement(SUPPLEMENT_DESCRIPTION_CONTROLS.get())
                .multiValued()
                .valuePlaceholder(INFO_LDAP_CONTROL_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "ldapVersion" integer argument.
     *
     * @return The "ldapVersion" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument ldapVersionArgument() throws ArgumentException {
        return IntegerArgument.builder(OPTION_LONG_PROTOCOL_VERSION)
                .shortIdentifier(OPTION_SHORT_PROTOCOL_VERSION)
                .description(INFO_DESCRIPTION_VERSION.get())
                .defaultValue(3)
                .valuePlaceholder(INFO_PROTOCOL_VERSION_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "quiet" boolean argument.
     *
     * @return The "quiet" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument quietArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_QUIET)
                .shortIdentifier(OPTION_SHORT_QUIET)
                .description(INFO_DESCRIPTION_QUIET.get())
                .buildArgument();
    }
    /**
     * Returns the "no-op" boolean argument. <br>
     * <i> N.B : the 'n' short option is also used by backendid, newGroupName, newPassword, no-prompt.</i>
     *
     * @return The "no-op" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument noOpArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_DRYRUN)
                .shortIdentifier(OPTION_SHORT_DRYRUN)
                .description(INFO_DESCRIPTION_NOOP.get())
                .buildArgument();
    }
    /**
     * Returns the "no-prompt" boolean argument. <br>
     * <i> N.B : the 'n' short option is also used by backendid, newGroupName, newPassword, no-prompt.</i>
     *
     * @return The "no-prompt" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument noPromptArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_NO_PROMPT)
                .shortIdentifier(OPTION_SHORT_NO_PROMPT)
                .description(INFO_DESCRIPTION_NO_PROMPT.get())
                .buildArgument();
    }
    /**
     * Returns the "acceptLicense" boolean argument.
     *
     * @return The "acceptLicense" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument acceptLicenseArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_ACCEPT_LICENSE)
                .description(INFO_OPTION_ACCEPT_LICENSE.get())
                .buildArgument();
    }
    /**
     * Returns the "trustAll" boolean argument.
     *
     * @return The "trustAll" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument trustAllArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_TRUSTALL)
                .shortIdentifier(OPTION_SHORT_TRUSTALL)
                .description(INFO_DESCRIPTION_TRUSTALL.get())
                .buildArgument();
    }
    /**
     * Returns the "trustStorePath" string argument.
     *
     * @return The "trustStorePath" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument trustStorePathArgument() throws ArgumentException {
        return trustStorePathArgument(null);
    }
    /**
     * Returns the "trustStorePath" string argument initialized with the provided default value.
     *
     * @param defaultValue
     *          The "trustStorePath" argument default value
     * @return The "trustStorePath" string argument initialized with the provided default value.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument trustStorePathArgument(final String defaultValue) throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_TRUSTSTOREPATH)
                .shortIdentifier(OPTION_SHORT_TRUSTSTOREPATH)
                .description(INFO_DESCRIPTION_TRUSTSTOREPATH.get())
                .defaultValue(defaultValue)
                .valuePlaceholder(INFO_TRUSTSTOREPATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "truststorepw" string argument.
     *
     * @return The "truststorepw" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument trustStorePasswordArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_TRUSTSTORE_PWD)
                .shortIdentifier(OPTION_SHORT_TRUSTSTORE_PWD)
                .description(INFO_DESCRIPTION_TRUSTSTOREPASSWORD.get())
                .valuePlaceholder(INFO_TRUSTSTORE_PWD_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "trustStorePasswordFile" file argument.
     *
     * @return The "trustStorePasswordFile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static FileBasedArgument trustStorePasswordFileArgument() throws ArgumentException {
        return FileBasedArgument.builder(OPTION_LONG_TRUSTSTORE_PWD_FILE)
                .shortIdentifier(OPTION_SHORT_TRUSTSTORE_PWD_FILE)
                .description(INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE.get())
                .valuePlaceholder(INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns a "connectTimeout" hidden integer argument.
     *
     * @return A "connectTimeout" hidden integer argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument connectTimeOutHiddenArgument() throws ArgumentException {
        return connectTimeOutArgument(true);
    }
    /**
     * Returns a "connectTimeout" integer argument.
     *
     * @return A "connectTimeout" integer argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument connectTimeOutArgument() throws ArgumentException {
        return connectTimeOutArgument(false);
    }
    private static IntegerArgument connectTimeOutArgument(final boolean hidden) throws ArgumentException {
        final IntegerArgument.Builder builder = IntegerArgument.builder(OPTION_LONG_CONNECT_TIMEOUT)
                .description(INFO_DESCRIPTION_CONNECTION_TIMEOUT.get())
                .lowerBound(0)
                .defaultValue(DEFAULT_LDAP_CONNECT_TIMEOUT)
                .valuePlaceholder(INFO_TIMEOUT_PLACEHOLDER.get());
        if (hidden) {
            builder.hidden();
        }
        return builder.buildArgument();
    }
    /**
     * Returns the "CLI" boolean argument. <br>
     * <i> N.B : the 'i' short option is also used by encoding.</i>
     *
     * @return The "CLI" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument cliArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_CLI)
                .shortIdentifier(OPTION_SHORT_CLI)
                .description(INFO_ARGUMENT_DESCRIPTION_CLI.get())
                .buildArgument();
    }
    /**
     * Returns the "configfile" string argument. <br>
     * <i> N.B : the 'f' short option is also used by filename</i>
     *
     * @return The "configfile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument configFileArgument() throws ArgumentException {
        return StringArgument.builder("configFile")
                .shortIdentifier('f')
                .description(INFO_DESCRIPTION_CONFIG_FILE.get())
                .hidden()
                .required()
                .valuePlaceholder(INFO_CONFIGFILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "configclass" string argument.
     *
     * @param configFileHandlerName
     *            The config file handler name.
     * @return The "configclass" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument configClassArgument(final String configFileHandlerName) throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_CONFIG_CLASS)
                .shortIdentifier(OPTION_SHORT_CONFIG_CLASS)
                .description(INFO_DESCRIPTION_CONFIG_CLASS.get())
                .hidden()
                .required()
                .defaultValue(configFileHandlerName)
                .valuePlaceholder(INFO_CONFIGCLASS_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "baseDN" string argument.
     *
     * @return The "baseDN" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument baseDNArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_BASEDN)
                .shortIdentifier(OPTION_SHORT_BASEDN)
                .description(INFO_ARGUMENT_DESCRIPTION_BASEDN.get())
                .multiValued()
                .valuePlaceholder(INFO_BASEDN_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "bindDN" string argument. <br/>
     * <i> N.B : the 'D' short option is also used by rootUserDN.</i>
     *
     * @param defaultBindDN
     *            The default bind DN.
     * @return The "bindDN" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument bindDNArgument(final String defaultBindDN) throws ArgumentException {
        return bindDNArgument(defaultBindDN, INFO_DESCRIPTION_BINDDN.get());
    }
    /**
     * Returns the "bindDN" string argument. <br/>
     * <i> N.B : the 'D' short option is also used by rootUserDN.</i>
     *
     * @param defaultBindDN
     *            The default bind DN.
     * @param description
     *            The localized description to print in help messages.
     * @return The "bindDN" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument bindDNArgument(final String defaultBindDN, final LocalizableMessage description)
            throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_BINDDN)
                .shortIdentifier(OPTION_SHORT_BINDDN)
                .description(description)
                .defaultValue(defaultBindDN)
                .valuePlaceholder(INFO_BINDDN_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "bindPassword" string argument.
     *
     * @return The "bindPassword" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument bindPasswordArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_BINDPWD)
                .shortIdentifier(OPTION_SHORT_BINDPWD)
                .description(INFO_DESCRIPTION_BINDPASSWORD.get())
                .valuePlaceholder(INFO_BINDPWD_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "bindPasswordFile" file argument.
     *
     * @return The "bindPasswordFile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static FileBasedArgument bindPasswordFileArgument() throws ArgumentException {
        return FileBasedArgument.builder(OPTION_LONG_BINDPWD_FILE)
                .shortIdentifier(OPTION_SHORT_BINDPWD_FILE)
                .description(INFO_DESCRIPTION_BINDPASSWORDFILE.get())
                .valuePlaceholder(INFO_BINDPWD_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "addbaseentry" boolean argument.
     * <br><i> N.B : the 'a' short option is also used by backupall, defaultAdd.</i>
     *
     * @return The "addbaseentry" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument addBaseEntryArgument() throws ArgumentException {
        return BooleanArgument.builder("addBaseEntry")
                .shortIdentifier('a')
                .description(INFO_ARGUMENT_DESCRIPTION_ADDBASE.get())
                .buildArgument();
    }
    /**
     * Returns the "rejectfile" string argument. <br>
     * <i> N.B : the 'R' short option is also used by restart, serverRoot.</i>
     *
     * @return The "rejectfile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument rejectedImportLdifArgument() throws ArgumentException {
        return StringArgument.builder("rejectFile")
                .shortIdentifier('R')
                .description(INFO_GENERAL_DESCRIPTION_REJECTED_FILE.get())
                .valuePlaceholder(INFO_REJECT_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "remote" boolean argument. <br>
     * <i> N.B : the 'r' short option is also used by useSASLExternal, stopreason.</i>
     *
     * @return The "remote" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument remoteArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_REMOTE)
                .shortIdentifier(OPTION_SHORT_REMOTE)
                .description(INFO_DESCRIPTION_REMOTE.get())
                .buildArgument();
    }
    /**
     * Returns the "reportauthzid" boolean argument.
     *
     * @return The "reportauthzid" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument reportAuthzIdArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_REPORT_AUTHZ_ID)
                .shortIdentifier('E')
                .description(INFO_DESCRIPTION_REPORT_AUTHZID.get())
                .buildArgument();
    }
    /**
     * Returns the "restart" boolean argument. <br>
     * <i> N.B : the 'R' short option is also used by rejectfile, serverRoot.</i>
     *
     * @return The "restart" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument restartArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_RESTART)
                .shortIdentifier('R')
                .description(INFO_DESCRIPTION_RESTART.get())
                .buildArgument();
    }
    /**
     * Returns the "skip file" string argument.
     *
     * @return The "skipFile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument skippedImportFileArgument() throws ArgumentException {
        return StringArgument.builder("skipFile")
                .description(INFO_GENERAL_DESCRIPTION_SKIPPED_FILE.get())
                .valuePlaceholder(INFO_SKIP_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "sample data" integer argument. <br>
     * <i> N.B : the 'd' short option is also used by backupdirectory, disableservice.</i>
     *
     * @return The "sampleData" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument sampleDataArgument() throws ArgumentException {
        return IntegerArgument.builder("sampleData")
                .shortIdentifier('d')
                .description(INFO_SETUP_DESCRIPTION_SAMPLE_DATA.get())
                .lowerBound(0)
                .defaultValue(0)
                .valuePlaceholder(INFO_NUM_ENTRIES_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "sasloption" string argument. <br>
     * <i> N.B : the 'o' short option is also used by outputLDIF.</i>
     *
     * @return The "sasloption" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument saslArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_SASLOPTION)
                .shortIdentifier(OPTION_SHORT_SASLOPTION)
                .description(INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS.get())
                .multiValued()
                .valuePlaceholder(INFO_SASL_OPTION_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "searchScope" string argument.<br>
     * <i> N.B : the 's' short option is also used by servicestate, sourceldif, randomSeed, script-friendly.</i>
     *
     * @return The "searchScope" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static MultiChoiceArgument<SearchScope> searchScopeArgument() throws ArgumentException {
        return MultiChoiceArgument.<SearchScope>builder(OPTION_LONG_SEARCHSCOPE)
                .shortIdentifier(OPTION_SHORT_SEARCHSCOPE)
                .description(INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE.get())
                .allowedValues(SearchScope.values())
                .defaultValue(SearchScope.WHOLE_SUBTREE)
                .valuePlaceholder(INFO_SEARCH_SCOPE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "script-friendly" boolean argument.<br>
     * <i> N.B : the 's' short option is also used by searchScope, servicestate, sourceldif, randomSeed.</i>
     *
     * @return The "script-friendly" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument scriptFriendlyArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_SCRIPT_FRIENDLY)
                .shortIdentifier(OPTION_SHORT_SCRIPT_FRIENDLY)
                .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get())
                .buildArgument();
    }
    /**
     * Returns the "LDAP port" integer argument.
     *
     * @param defaultLdapPort
     *            Default LDAP Connector port.
     * @return The "ldapPort" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument ldapPortArgument(final int defaultLdapPort) throws ArgumentException {
        return IntegerArgument.builder("ldapPort")
                .shortIdentifier(OPTION_SHORT_PORT)
                .description(INFO_ARGUMENT_DESCRIPTION_LDAPPORT.get())
                .range(1, 65535)
                .defaultValue(defaultLdapPort)
                .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "Admin port" integer argument.
     *
     * @param defaultAdminPort
     *            Default Administration Connector port.
     * @return The "adminConnectorPort" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument adminLdapPortArgument(final int defaultAdminPort) throws ArgumentException {
        return IntegerArgument.builder("adminConnectorPort")
                .description(INFO_ARGUMENT_DESCRIPTION_ADMINCONNECTORPORT.get())
                .range(1, 65535)
                .defaultValue(defaultAdminPort)
                .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "advanced" boolean argument.
     *
     * @return The "advanced" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument advancedModeArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_ADVANCED)
                .description(INFO_DESCRIPTION_ADVANCED.get())
                .buildArgument();
    }
    /**
     * Returns the "JMX port" integer argument.
     *
     * @param defaultJMXPort
     *            Default JMX port.
     * @return The "jmxPort" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument jmxPortArgument(final int defaultJMXPort) throws ArgumentException {
        return IntegerArgument.builder("jmxPort")
                .shortIdentifier('x')
                .description(INFO_ARGUMENT_DESCRIPTION_SKIPPORT.get())
                .range(1, 65535)
                .defaultValue(defaultJMXPort)
                .valuePlaceholder(INFO_JMXPORT_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "skipPortCheck" boolean argument.
     *
     * @return The "skipPortCheck" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument skipPortCheckArgument() throws ArgumentException {
        return BooleanArgument.builder("skipPortCheck")
                .shortIdentifier('S')
                .description(INFO_ARGUMENT_DESCRIPTION_SKIPPORT.get())
                .buildArgument();
    }
    /**
     * Returns the "startTLS" boolean argument.
     *
     * @return The "startTLS" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument startTLSArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_START_TLS)
                .shortIdentifier(OPTION_SHORT_START_TLS)
                .description(INFO_DESCRIPTION_START_TLS.get())
                .buildArgument();
    }
    /**
     * Returns the "rootUserDN" string argument. <br>
     * <i> N.B : the 'D' short option is also used by bindDN.</i>
     *
     * @return The "rootUserDN" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument rootDNArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_ROOT_USER_DN)
                .shortIdentifier(OPTION_SHORT_ROOT_USER_DN)
                .description(INFO_ARGUMENT_DESCRIPTION_ROOTDN.get())
                .defaultValue("cn=Directory Manager")
                .valuePlaceholder(INFO_ROOT_USER_DN_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "directory manager DN password" string argument.
     *
     * @return The "rootUserPassword" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument rootDNPwdArgument() throws ArgumentException {
        return StringArgument.builder("rootUserPassword")
                .shortIdentifier(OPTION_SHORT_BINDPWD)
                .description(INFO_ROOT_USER_PWD_PLACEHOLDER.get())
                .valuePlaceholder(INFO_ROOT_USER_PWD_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "directory manager DN password file" file argument.
     *
     * @return The "rootUserPasswordFile" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static FileBasedArgument rootDNPwdFileArgument() throws ArgumentException {
        return FileBasedArgument.builder("rootUserPasswordFile")
                .shortIdentifier(OPTION_SHORT_BINDPWD_FILE)
                .description(INFO_ARGUMENT_DESCRIPTION_ROOTPWFILE.get())
                .valuePlaceholder(INFO_ROOT_USER_PWD_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "enable window service" integer argument.
     *
     * @return The "enableWindowsService" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument enableWindowsServiceArgument() throws ArgumentException {
        return BooleanArgument.builder("enableWindowsService")
                .shortIdentifier('e')
                .description(INFO_ARGUMENT_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get())
                .buildArgument();
    }
    /**
     * Returns the "encoding" string argument. <br>
     * <i> N.B : the 'i' short option is also used by cli</i>
     *
     * @return The "encoding" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument encodingArgument() throws ArgumentException {
        return StringArgument.builder("encoding")
                .shortIdentifier('i')
                .description(INFO_DESCRIPTION_ENCODING.get())
                .valuePlaceholder(INFO_ENCODING_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "do not start" boolean argument.
     *
     * @return The "doNotStart" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument doNotStartArgument() throws ArgumentException {
        return BooleanArgument.builder("doNotStart")
                .shortIdentifier('O')
                .description(INFO_SETUP_DESCRIPTION_DO_NOT_START.get())
                .buildArgument();
    }
    /**
     * Returns the "displayCommand" boolean argument.
     *
     * @return The "displayCommand" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument displayEquivalentCommandArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_DISPLAY_EQUIVALENT)
                .description(INFO_DESCRIPTION_DISPLAY_EQUIVALENT.get())
                .buildArgument();
    }
    /**
     * Returns the "commandFilePath" string argument.
     *
     * @param description
     *            The description of this argument.
     * @return The "commandFilePath" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument equivalentCommandFileArgument(final LocalizableMessage description)
            throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH)
                .description(description)
                .valuePlaceholder(INFO_PATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "filename" string argument.
     * <i> N.B : the 'f' short option is also used by configfile</i>
     * @param description
     *            The description of this argument.
     * @return The "filename" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument filenameArgument(final LocalizableMessage description) throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_FILENAME)
                .shortIdentifier(OPTION_SHORT_FILENAME)
                .description(description)
                .valuePlaceholder(INFO_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "enable start TLS" boolean argument.
     *
     * @return The "enableStartTLS" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument enableTLSArgument() throws ArgumentException {
        return BooleanArgument.builder("enableStartTLS")
                .shortIdentifier(OPTION_SHORT_START_TLS)
                .description(INFO_SETUP_DESCRIPTION_ENABLE_STARTTLS.get())
                .buildArgument();
    }
    /**
     * Returns the "ldaps port" integer argument. <br>
     * <i> N.B : the 'Z' short option is also used by useSSL.</i>
     *
     * @param defaultSecurePort
     *            Default value for the LDAPS port.
     * @return The "ldapsPort" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static IntegerArgument ldapsPortArgument(final int defaultSecurePort) throws ArgumentException {
        return IntegerArgument.builder("ldapsPort")
                .shortIdentifier(OPTION_SHORT_USE_SSL)
                .description(INFO_ARGUMENT_DESCRIPTION_LDAPSPORT.get())
                .range(1, 65535)
                .defaultValue(defaultSecurePort)
                .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "ldiffile" string argument.
     *
     * @param description
     *            The description of this argument.
     * @return The "ldapsPort" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument ldifFileArgument(final LocalizableMessage description) throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_LDIF_FILE)
                .shortIdentifier(OPTION_SHORT_LDIF_FILE)
                .description(description)
                .multiValued()
                .valuePlaceholder(INFO_LDIFFILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "generate self certificate" boolean argument.
     *
     * @return The "generateSelfSignedCertificate" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument generateSelfSignedArgument() throws ArgumentException {
        return BooleanArgument.builder("generateSelfSignedCertificate")
                .description(INFO_ARGUMENT_DESCRIPTION_USE_SELF_SIGNED_CERTIFICATE.get())
                .buildArgument();
    }
    /**
     * Returns the "hostname" string argument.
     *
     * @param defaultHostName
     *            The default host name value.
     * @return The "hostname" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument hostNameArgument(final String defaultHostName) throws ArgumentException {
        return hostNameArgument(defaultHostName, null);
    }
    /**
     * Returns the "hostname" string argument.
     *
     * @param defaultHostName
     *            The default host name value.
     * @param description
     *            The custom description.
     * @return The "hostname" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument hostNameArgument(final String defaultHostName, final LocalizableMessage description)
            throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_HOST)
                .shortIdentifier(OPTION_SHORT_HOST)
                .description(description != null ? description : INFO_ARGUMENT_DESCRIPTION_HOST_NAME.get())
                .defaultValue(defaultHostName)
                .valuePlaceholder(INFO_HOST_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "use PKCS11 key store" boolean argument.
     *
     * @return The "usePkcs11Keystore" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument usePKCS11KeystoreArgument() throws ArgumentException {
        return BooleanArgument.builder("usePkcs11Keystore")
                .description(INFO_ARGUMENT_DESCRIPTION_USE_PKCS11.get())
                .buildArgument();
    }
    /**
     * Returns the "use java key store" string argument.
     *
     * @return The "useJavaKeystore" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument useJavaKeyStoreArgument() throws ArgumentException {
        return StringArgument.builder("useJavaKeystore")
                .description(INFO_ARGUMENT_DESCRIPTION_USE_JAVAKEYSTORE.get())
                .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "use JCEKS" string argument.
     *
     * @return The "useJCEKS" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument useJCEKSArgument() throws ArgumentException {
        return StringArgument.builder("useJCEKS")
                .description(INFO_ARGUMENT_DESCRIPTION_USE_JCEKS.get())
                .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "use PKCS12 key store" string argument.
     *
     * @return The "usePkcs12keyStore" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument usePKCS12KeyStoreArgument() throws ArgumentException {
        return StringArgument.builder("usePkcs12keyStore")
                .description(INFO_ARGUMENT_DESCRIPTION_USE_PKCS12.get())
                .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "useSSL" boolean argument. <br>
     * <i> N.B : the 'Z' short option is also used by ldapsport.</i>
     *
     * @return The "useSSL" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static BooleanArgument useSSLArgument() throws ArgumentException {
        return BooleanArgument.builder(OPTION_LONG_USE_SSL)
                .shortIdentifier(OPTION_SHORT_USE_SSL)
                .description(INFO_DESCRIPTION_USE_SSL.get())
                .buildArgument();
    }
    /**
     * Returns the "key store password" string argument.
     *
     * @return The "keyStorePassword" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument keyStorePasswordArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_KEYSTORE_PWD)
                .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD)
                .description(INFO_ARGUMENT_DESCRIPTION_KEYSTOREPASSWORD.get())
                .valuePlaceholder(INFO_KEYSTORE_PWD_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "key store password file" file argument.
     *
     * @return The "keyStorePassword" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static FileBasedArgument keyStorePasswordFileArgument() throws ArgumentException {
        return FileBasedArgument.builder(OPTION_LONG_KEYSTORE_PWD_FILE)
                .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD_FILE)
                .description(INFO_ARGUMENT_DESCRIPTION_KEYSTOREPASSWORD_FILE.get())
                .valuePlaceholder(INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "keyStorePath" string argument.
     *
     * @return The "keyStorePath" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument keyStorePathArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_KEYSTOREPATH)
                .shortIdentifier(OPTION_SHORT_KEYSTOREPATH)
                .description(INFO_DESCRIPTION_KEYSTOREPATH.get())
                .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "key store password file" string argument.
     *
     * @return The "keyStorePassword" argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument certNickNameArgument() throws ArgumentException {
        return StringArgument.builder(OPTION_LONG_CERT_NICKNAME)
                .shortIdentifier(OPTION_SHORT_CERT_NICKNAME)
                .description(INFO_ARGUMENT_DESCRIPTION_CERT_NICKNAME.get())
                .multiValued()
                .valuePlaceholder(INFO_NICKNAME_PLACEHOLDER.get())
                .buildArgument();
    }
    /**
     * Returns the "admin uid" string argument with the provided description.
     *
     * @param description
     *            The argument localizable description.
     * @return The "admin uid" string argument with the provided description.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument adminUid(final LocalizableMessage description) throws ArgumentException {
        return adminUidArgument(false, description);
    }
    /**
     * Returns the "admin uid" hidden string argument.
     *
     * @param description
     *            The argument localizable description.
     * @return The "admin uid" hidden string argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to create this argument.
     */
    public static StringArgument adminUidHiddenArgument(final LocalizableMessage description)
            throws ArgumentException {
        return adminUidArgument(true, description);
    }
    private static StringArgument adminUidArgument(final boolean hidden, final LocalizableMessage description)
            throws ArgumentException {
        final StringArgument.Builder builder = StringArgument.builder(OPTION_LONG_ADMIN_UID)
                .shortIdentifier('I')
                .description(description)
                .defaultValue(CliConstants.GLOBAL_ADMIN_UID)
                .valuePlaceholder(INFO_ADMINUID_PLACEHOLDER.get());
        if (hidden) {
            builder.hidden();
        }
        return builder.buildArgument();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ConnectionFactoryProvider.java
New file
@@ -0,0 +1,841 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2011-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.ArgumentConstants.*;
import static com.forgerock.opendj.cli.CliConstants.DEFAULT_LDAP_PORT;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.cli.Utils.getHostNameForLdapUrl;
import static com.forgerock.opendj.cli.Utils.throwIfArgumentsConflict;
import static org.forgerock.opendj.ldap.LDAPConnectionFactory.AUTHN_BIND_REQUEST;
import static org.forgerock.opendj.ldap.LDAPConnectionFactory.CONNECT_TIMEOUT;
import static org.forgerock.opendj.ldap.LDAPConnectionFactory.SSL_CONTEXT;
import static org.forgerock.opendj.ldap.LDAPConnectionFactory.SSL_USE_STARTTLS;
import static com.forgerock.opendj.cli.CommonArguments.*;
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.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.KeyManagers;
import org.forgerock.opendj.ldap.LDAPConnectionFactory;
import org.forgerock.opendj.ldap.SSLContextBuilder;
import org.forgerock.opendj.ldap.TrustManagers;
import org.forgerock.opendj.ldap.controls.AuthorizationIdentityRequestControl;
import org.forgerock.opendj.ldap.controls.PasswordPolicyRequestControl;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.CRAMMD5SASLBindRequest;
import org.forgerock.opendj.ldap.requests.DigestMD5SASLBindRequest;
import org.forgerock.opendj.ldap.requests.ExternalSASLBindRequest;
import org.forgerock.opendj.ldap.requests.GSSAPISASLBindRequest;
import org.forgerock.opendj.ldap.requests.PlainSASLBindRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.util.Options;
import org.forgerock.util.time.Duration;
/**
 * A connection factory designed for use with command line tools.
 */
public final class ConnectionFactoryProvider {
    /** The Logger. */
    static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
    /** The 'hostName' global argument. */
    private StringArgument hostNameArg;
    /** The 'port' global argument. */
    private IntegerArgument portArg;
    /** The 'bindDN' global argument. */
    private StringArgument bindNameArg;
    /** The 'bindPasswordFile' global argument. */
    private FileBasedArgument bindPasswordFileArg;
    /** The 'password' value. */
    private char[] password;
    /** The 'bindPassword' global argument. */
    private StringArgument bindPasswordArg;
    /** The 'connectTimeOut' global argument. */
    private IntegerArgument connectTimeOut;
    /** The 'trustAllArg' global argument. */
    private BooleanArgument trustAllArg;
    /** The 'trustStore' global argument. */
    private StringArgument trustStorePathArg;
    /** The 'trustStorePassword' global argument. */
    private StringArgument trustStorePasswordArg;
    /** The 'trustStorePasswordFile' global argument. */
    private FileBasedArgument trustStorePasswordFileArg;
    /** The 'keyStore' global argument. */
    private StringArgument keyStorePathArg;
    /** The 'keyStorePassword' global argument. */
    private StringArgument keyStorePasswordArg;
    /** The 'keyStorePasswordFile' global argument. */
    private FileBasedArgument keyStorePasswordFileArg;
    /** The 'certNicknameArg' global argument. */
    private StringArgument certNicknameArg;
    /** The 'useSSLArg' global argument. */
    private BooleanArgument useSSLArg;
    /** The 'useStartTLSArg' global argument. */
    private BooleanArgument useStartTLSArg;
    /** Argument indicating a SASL option. */
    private StringArgument saslOptionArg;
    /**
     * Whether to request that the server return the authorization ID in the
     * bind response.
     */
    private final BooleanArgument reportAuthzIDArg;
    /** Whether to use the password policy control in the bind request. */
    private final BooleanArgument usePasswordPolicyControlArg;
    /** The SSL context linked to this connection. */
    private SSLContext sslContext;
    /**  The basic connection factory. */
    private ConnectionFactory connFactory;
    /** The bind request to connect with. */
    private BindRequest bindRequest;
    /** The console application linked to this connection in interactive mode. */
    private final ConsoleApplication app;
    /** If this connection should be an admin connection. */
    private boolean isAdminConnection;
    /**
     * Default constructor to create a connection factory designed for use with command line tools,
     * adding basic LDAP connection arguments to the specified parser (e.g: hostname, bindname...etc).
     *
     * @param argumentParser
     *            The argument parser.
     * @param app
     *            The console application linked to this connection factory.
     * @throws ArgumentException
     *             If an error occurs during parsing the arguments.
     */
    public ConnectionFactoryProvider(final ArgumentParser argumentParser,
            final ConsoleApplication app) throws ArgumentException {
        this(argumentParser, app, "", DEFAULT_LDAP_PORT, false);
    }
    /**
     * Constructor to create a connection factory designed for use with command line tools,
     * adding basic LDAP connection arguments to the specified parser (e.g: hostname, bindname...etc).
     *
     * @param argumentParser
     *            The argument parser.
     * @param app
     *            The console application linked to this connection factory.
     * @param defaultBindDN
     *            The bind DN default's value.
     * @param defaultPort
     *            The LDAP port default's value.
     * @param alwaysSSL
     *            {@code true} if this connection should be used with SSL.
     * @throws ArgumentException
     *             If an error occurs during parsing the elements.
     */
    public ConnectionFactoryProvider(final ArgumentParser argumentParser,
            final ConsoleApplication app, final String defaultBindDN, final int defaultPort,
            final boolean alwaysSSL) throws ArgumentException {
        this.app = app;
        useSSLArg = useSSLArgument();
        if (!alwaysSSL) {
            argumentParser.addLdapConnectionArgument(useSSLArg);
        } else {
            // simulate that the useSSL arg has been given in the CLI
            useSSLArg.setPresent(true);
        }
        useStartTLSArg = startTLSArgument();
        if (!alwaysSSL) {
            argumentParser.addLdapConnectionArgument(useStartTLSArg);
        }
        String defaultHostName;
        try {
            defaultHostName = InetAddress.getLocalHost().getHostName();
        } catch (final Exception e) {
            defaultHostName = "Unknown (" + e + ")";
        }
        hostNameArg = hostNameArgument(defaultHostName);
        argumentParser.addLdapConnectionArgument(hostNameArg);
        LocalizableMessage portDescription = INFO_DESCRIPTION_PORT.get();
        if (alwaysSSL) {
            portDescription = INFO_DESCRIPTION_ADMIN_PORT.get();
        }
        portArg = portArgument(defaultPort, portDescription);
        argumentParser.addLdapConnectionArgument(portArg);
        bindNameArg = bindDNArgument(defaultBindDN);
        argumentParser.addLdapConnectionArgument(bindNameArg);
        bindPasswordArg = bindPasswordArgument();
        argumentParser.addLdapConnectionArgument(bindPasswordArg);
        bindPasswordFileArg = bindPasswordFileArgument();
        argumentParser.addLdapConnectionArgument(bindPasswordFileArg);
        saslOptionArg = saslArgument();
        argumentParser.addLdapConnectionArgument(saslOptionArg);
        trustAllArg = trustAllArgument();
        argumentParser.addLdapConnectionArgument(trustAllArg);
        trustStorePathArg = trustStorePathArgument();
        argumentParser.addLdapConnectionArgument(trustStorePathArg);
        trustStorePasswordArg = trustStorePasswordArgument();
        argumentParser.addLdapConnectionArgument(trustStorePasswordArg);
        trustStorePasswordFileArg = trustStorePasswordFileArgument();
        argumentParser.addLdapConnectionArgument(trustStorePasswordFileArg);
        keyStorePathArg = keyStorePathArgument();
        argumentParser.addLdapConnectionArgument(keyStorePathArg);
        keyStorePasswordArg = keyStorePasswordArgument();
        argumentParser.addLdapConnectionArgument(keyStorePasswordArg);
        keyStorePasswordFileArg = keyStorePasswordFileArgument();
        argumentParser.addLdapConnectionArgument(keyStorePasswordFileArg);
        certNicknameArg = certNickNameArgument();
        argumentParser.addLdapConnectionArgument(certNicknameArg);
        reportAuthzIDArg = reportAuthzIdArgument();
        argumentParser.addArgument(reportAuthzIDArg);
        connectTimeOut = connectTimeOutHiddenArgument();
        argumentParser.addArgument(connectTimeOut);
        usePasswordPolicyControlArg =
                BooleanArgument.builder(OPTION_LONG_USE_PW_POLICY_CTL)
                        .description(INFO_DESCRIPTION_USE_PWP_CONTROL.get())
                        .buildAndAddToParser(argumentParser);
    }
    /**
     * Returns the connect time out.
     *
     * @return The connect time out value.
     */
    public int getConnectTimeout() {
        if (connectTimeOut.isPresent()) {
            try {
                return connectTimeOut.getIntValue();
            } catch (ArgumentException e) {
                return Integer.valueOf(connectTimeOut.getDefaultValue());
            }
        }
        return Integer.valueOf(connectTimeOut.getDefaultValue());
    }
    /**
     * Returns the host name if the argument is present otherwise, if the application
     * is interactive, prompt the user for it.
     *
     * @return The host name value.
     * @throws ArgumentException
     *             If the host name cannot be retrieved.
     */
    public String getHostname() throws ArgumentException {
        String value = "";
        if (hostNameArg.isPresent()) {
            value = hostNameArg.getValue();
        } else if (app.isInteractive()) {
            try {
                value = app.readInput(INFO_DESCRIPTION_HOST.get(), getHostNameDefaultValue(value));
                app.println();
                hostNameArg.addValue(value);
                hostNameArg.setPresent(true);
            } catch (ClientException e) {
                throw new ArgumentException(ERR_ERROR_CANNOT_READ_HOST_NAME.get(), e);
            }
        } else {
            return getHostNameDefaultValue(value);
        }
        return getHostNameForLdapUrl(value);
    }
    private String getHostNameDefaultValue(String fallbackValue) {
        return hostNameArg.getDefaultValue() != null ? hostNameArg.getDefaultValue() : fallbackValue;
    }
    /**
     * Get the port which has to be used for the command.
     *
     * @return The port specified by the command line argument, or the default value, if not specified.
     */
    public int getPort() {
        if (portArg.isPresent()) {
            try {
                return portArg.getIntValue();
            } catch (ArgumentException e) {
                return Integer.valueOf(portArg.getDefaultValue());
            }
        } else if (app.isInteractive()) {
            final LocalizableMessage portMsg =
                    isAdminConnection ? INFO_DESCRIPTION_ADMIN_PORT.get() : INFO_DESCRIPTION_PORT.get();
            int value = app.askPort(portMsg, Integer.valueOf(portArg.getDefaultValue()), logger);
            app.println();
            portArg.addValue(Integer.toString(value));
            portArg.setPresent(true);
            return value;
        }
        return Integer.valueOf(portArg.getDefaultValue());
    }
    /**
     * Indicate if the SSL mode is required.
     *
     * @return True if SSL mode is required
     */
    public boolean useSSL() {
        return useSSLArg.isPresent();
    }
    /**
     * Indicate if the startTLS mode is required.
     *
     * @return True if startTLS mode is required
     */
    public boolean useStartTLS() {
        return useStartTLSArg.isPresent();
    }
    /**
     * Constructs a connection factory for pre-authenticated connections. Checks if any conflicting arguments are
     * present, build the connection with selected arguments and returns the connection factory. If the application is
     * interactive, it will prompt the user for missing parameters.
     *
     * @return The connection factory.
     * @throws ArgumentException
     *         If an error occurs during the parsing of the arguments (conflicting arguments or if an error occurs
     *         during building SSL context).
     */
    public ConnectionFactory getAuthenticatedConnectionFactory() throws ArgumentException {
        return getConnectionFactory(true);
    }
    /**
     * Constructs a connection factory for unauthenticated connections. Checks if any conflicting arguments are present,
     * build the connection with selected arguments and returns the connection factory. If the application is
     * interactive, it will prompt the user for missing parameters.
     *
     * @return The connection factory.
     * @throws ArgumentException
     *         If an error occurs during the parsing of the arguments (conflicting arguments or if an error occurs
     *         during building SSL context).
     */
    public ConnectionFactory getUnauthenticatedConnectionFactory() throws ArgumentException {
        return getConnectionFactory(false);
    }
    private ConnectionFactory getConnectionFactory(boolean usePreAuthentication) throws ArgumentException {
        if (connFactory == null) {
            checkForConflictingArguments();
            if (app.isInteractive()) {
                boolean portIsMissing = !portArg.isPresent() || portArg.getIntValue() == 0;
                boolean bindPwdIsMissing = !bindPasswordArg.isPresent() && !bindPasswordFileArg.isPresent();
                if (!hostNameArg.isPresent() || portIsMissing || !bindNameArg.isPresent() || bindPwdIsMissing) {
                    app.printHeader(INFO_LDAP_CONN_HEADING_CONNECTION_PARAMETERS.get());
                }
                if (!hostNameArg.isPresent()) {
                    getHostname();
                }
                if (portIsMissing) {
                    getPort();
                }
                if (!bindNameArg.isPresent()) {
                    getBindName();
                }
                if (bindPwdIsMissing) {
                    getPassword();
                }
            }
            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);
            }
            Options options = Options.defaultOptions();
            if (sslContext != null) {
                options.set(SSL_CONTEXT, sslContext)
                    .set(SSL_USE_STARTTLS, useStartTLSArg.isPresent());
            }
            options.set(CONNECT_TIMEOUT, new Duration((long) getConnectTimeout(), TimeUnit.MILLISECONDS));
            if (usePreAuthentication) {
                options.set(AUTHN_BIND_REQUEST, getBindRequest());
            }
            connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), portArg.getIntValue(), options);
        }
        return connFactory;
    }
    /**
     * Verifies if the connection arguments are not conflicting together or if they are readable.
     *
     * @throws ArgumentException
     *             If arguments are conflicting or if the files cannot be read,
     *             an argument exception is thrown.
     */
    private void checkForConflictingArguments() throws ArgumentException {
        throwIfArgumentsConflict(bindPasswordArg, bindPasswordFileArg);
        throwIfArgumentsConflict(trustAllArg, trustStorePathArg);
        throwIfArgumentsConflict(trustAllArg, trustStorePasswordArg);
        throwIfArgumentsConflict(trustAllArg, trustStorePasswordFileArg);
        throwIfArgumentsConflict(trustStorePasswordArg, trustStorePasswordFileArg);
        throwIfArgumentsConflict(useStartTLSArg, useSSLArg);
        if (trustStorePathArg.isPresent()) {
            // Check that the path exists and is readable
            final String value = trustStorePathArg.getValue();
            if (!canReadPath(value)) {
                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 (!canReadPath(value)) {
                final LocalizableMessage message = ERR_CANNOT_READ_KEYSTORE.get(value);
                throw new ArgumentException(message);
            }
        }
    }
    /**
     * Returns {@code true} if we can read on the provided path and
     * {@code false} otherwise.
     *
     * @param path
     *            the path.
     * @return {@code true} if we can read on the provided path and
     *         {@code false} otherwise.
     */
    private boolean canReadPath(final String path) {
        final File file = new File(path);
        return file.exists() && file.canRead();
    }
    private String getAuthID(final String mech) throws ArgumentException {
        String value = getAuthID();
        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 (ClientException e) {
                throw new ArgumentException(LocalizableMessage
                        .raw("Unable to read authentication ID"), e);
            }
        }
        if (value == null) {
            throw new ArgumentException(ERR_LDAPAUTH_SASL_AUTHID_REQUIRED.get(mech));
        }
        return value;
    }
    private String getAuthID() throws ArgumentException {
        return getSaslProperty(SASL_PROPERTY_AUTHID);
    }
    private String getAuthzID() throws ArgumentException {
        return getSaslProperty(SASL_PROPERTY_AUTHZID);
    }
    /**
     * Returns the bind name if the argument is present otherwise, in interactive mode, it
     * will prompt the user.
     *
     * @return The bind name used for this connection.
     * @throws ArgumentException
     *             If the bind name cannot be retrieved.
     */
    public String getBindName() throws ArgumentException {
        String value = "";
        if (bindNameArg.isPresent()) {
            value = bindNameArg.getValue();
        } else if (app.isInteractive()) {
            LocalizableMessage bindMsg;
            if (isAdminConnection) {
                bindMsg = INFO_DESCRIPTION_ADMIN_BINDDN.get();
            } else {
                bindMsg = INFO_DESCRIPTION_BINDDN.get();
            }
            try {
                value = app.readInput(bindMsg,
                        bindNameArg.getDefaultValue() == null ? value : bindNameArg.getDefaultValue());
                app.println();
                bindNameArg.clearValues();
                bindNameArg.addValue(value);
                bindNameArg.setPresent(true);
            } catch (ClientException e) {
                throw new ArgumentException(ERR_ERROR_CANNOT_READ_BIND_NAME.get(), e);
            }
        }
        return value;
    }
    /**
     * Returns the bind request for this connection.
     *
     * @return The bind request for this connection.
     * @throws ArgumentException
     *             If the arguments of this connection are wrong.
     */
    public BindRequest getBindRequest() throws ArgumentException {
        if (bindRequest == null) {
            String mech = getMechanism();
            if (mech == null) {
                if (bindNameArg.isPresent() || bindPasswordFileArg.isPresent()
                        || bindPasswordArg.isPresent()) {
                    bindRequest = Requests.newSimpleBindRequest(getBindName(), getPassword());
                }
            } else if (DigestMD5SASLBindRequest.SASL_MECHANISM_NAME.equals(mech)) {
                bindRequest =
                        Requests.newDigestMD5SASLBindRequest(
                                getAuthID(DigestMD5SASLBindRequest.SASL_MECHANISM_NAME),
                                getPassword()).setAuthorizationID(getAuthzID())
                                .setRealm(getRealm());
            } else if (CRAMMD5SASLBindRequest.SASL_MECHANISM_NAME.equals(mech)) {
                bindRequest =
                        Requests.newCRAMMD5SASLBindRequest(
                                getAuthID(CRAMMD5SASLBindRequest.SASL_MECHANISM_NAME),
                                getPassword());
            } else if (GSSAPISASLBindRequest.SASL_MECHANISM_NAME.equals(mech)) {
                bindRequest =
                        Requests.newGSSAPISASLBindRequest(
                                getAuthID(GSSAPISASLBindRequest.SASL_MECHANISM_NAME), getPassword())
                                .setKDCAddress(getKDC()).setRealm(getRealm()).setAuthorizationID(
                                        getAuthzID());
            } else if (ExternalSASLBindRequest.SASL_MECHANISM_NAME.equals(mech)) {
                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 (PlainSASLBindRequest.SASL_MECHANISM_NAME.equals(mech)) {
                bindRequest =
                        Requests.newPlainSASLBindRequest(
                                getAuthID(PlainSASLBindRequest.SASL_MECHANISM_NAME), getPassword())
                                .setAuthorizationID(getAuthzID());
            } else {
                throw new ArgumentException(ERR_LDAPAUTH_UNSUPPORTED_SASL_MECHANISM.get(mech));
            }
            if (reportAuthzIDArg.isPresent()) {
                bindRequest.addControl(AuthorizationIdentityRequestControl.newControl(false));
            }
            if (usePasswordPolicyControlArg.isPresent()) {
                bindRequest.addControl(PasswordPolicyRequestControl.newControl(false));
            }
        }
        return bindRequest;
    }
    private String getMechanism() throws ArgumentException {
        return getSaslProperty(SASL_PROPERTY_MECH);
    }
    private String getKDC() throws ArgumentException {
        return getSaslProperty(SASL_PROPERTY_KDC);
    }
    private String getRealm() throws ArgumentException {
        return getSaslProperty(SASL_PROPERTY_REALM);
    }
    private String getSaslProperty(String propertyName) throws ArgumentException {
        for (final String s : saslOptionArg.getValues()) {
            if (s.startsWith(propertyName)) {
                return parseSASLOptionValue(s);
            }
        }
        return null;
    }
    @Override
    public String toString() {
        return connFactory.toString();
    }
    /**
     * 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.
     * @throws IOException
     *             If there is an I/O or format problem with the keystore data.
     * @throws NoSuchAlgorithmException
     *             If a problem occurs while loading with the key store.
     * @throws CertificateException
     *             If a problem occurs while loading with the key store.
     */
    public 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 KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        try (final FileInputStream fos = new FileInputStream(keyStoreFile)) {
            keystore.load(fos, keyStorePIN);
        }
        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. In interactive mode, if
     * the password arguments are missing, the user will be prompted.
     *
     * @return The password stored into the specified file on by the command
     *         line argument, or empty it if not specified.
     * @throws ArgumentException
     *             If a problem occurs while interacting with the password.
     */
    public char[] getPassword() throws ArgumentException {
        char[] value = "".toCharArray();
        if (bindPasswordArg.isPresent()) {
            value = bindPasswordArg.getValue().toCharArray();
        } else if (bindPasswordFileArg.isPresent()) {
            value = bindPasswordFileArg.getValue().toCharArray();
        } else if (password != null) {
            return password;
        }
        if (value.length == 0 && app.isInteractive()) {
            LocalizableMessage msg;
            if (isAdminConnection) {
                msg = INFO_LDAPAUTH_PASSWORD_PROMPT.get(getBindName());
            } else {
                msg = INFO_DESCRIPTION_BINDPASSWORD.get();
            }
            try {
                value = app.readPassword(msg);
                app.println();
            } catch (ClientException e) {
                throw new ArgumentException(ERR_ERROR_CANNOT_READ_PASSWORD.get(), e);
            }
            password = value;
        }
        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 IOException
     *             If the trust store file could not be found or could not be read.
     * @throws GeneralSecurityException
     *             If a problem occurs while interacting with the trust store.
     */
    public 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(), null)));
        } else if (getTrustStore() != null) {
            tm = TrustManagers.checkValidityDates(TrustManagers.checkHostName(hostNameArg.getValue(),
                    TrustManagers.checkUsingTrustStore(getTrustStore(), getTrustStorePIN(), null)));
        }
        if (app != null && !app.isQuiet()) {
            return new PromptingTrustManager(app, tm);
        }
        return tm;
    }
    /**
     * 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, can be null.
     */
    private char[] 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 == null ? null : pwd.toCharArray();
    }
    private String parseSASLOptionValue(final String option) throws ArgumentException {
        final int equalPos = option.indexOf('=');
        if (equalPos == -1) {
            throw new ArgumentException(ERR_LDAP_CONN_CANNOT_PARSE_SASL_OPTION.get(option));
        }
        return option.substring(equalPos + 1, option.length());
    }
    /**
     * Specifies if this connection should be an administrator connection. If sets as one, the messages prompted to the
     * user will be different as a normal connection. E.g if set :
     *
     * <pre>
     * >>>> Specify OpenDJ LDAP connection parameters
     *
     * Directory server administration port number [4444]:
     * </pre>
     *
     * vs normal mode
     *
     * <pre>
     * >>>> Specify OpenDJ LDAP connection parameters
     *
     * Directory server port number [1389]:
     * </pre>
     */
    public void setIsAnAdminConnection() {
        isAdminConnection = true;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ConsoleApplication.java
New file
@@ -0,0 +1,767 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008-2009 Sun Microsystems, Inc.
 * Portions copyright 2011-2016 ForgeRock AS.
 * Portions copyright 2011 Nemanja Lukić
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.util.StaticUtils.*;
import java.io.BufferedReader;
import java.io.Console;
import java.io.EOFException;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
/**
 * This class provides an abstract base class which can be used as the basis of a console-based application.
 */
public abstract class ConsoleApplication {
    private static final int PROGRESS_LINE = 70;
    private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private final InputStream in = System.in;
    private final PrintStream out;
    private final PrintStream err;
    private final Console console = System.console();
    private boolean isProgressSuite;
    /** Defines the different line styles for output. */
    public enum Style {
        /** Defines a title. */
        TITLE,
        /** Defines a subtitle. */
        SUBTITLE,
        /** Defines a notice. */
        NOTICE,
        /** Defines a normal line. */
        NORMAL,
        /** Defines an error. */
        ERROR,
        /** Defines a warning. */
        WARNING
    }
    /**
     * Creates a new console application instance.
     */
    public ConsoleApplication() {
        this(System.out, System.err);
    }
    /**
     * Creates a new console application instance with provided standard and error out streams.
     *
     * @param out
     *            The output stream.
     * @param err
     *            The error stream.
     */
    public ConsoleApplication(PrintStream out, PrintStream err) {
        this.out = out;
        this.err = err;
    }
    /**
     * Returns the application error stream.
     *
     * @return The application error stream.
     */
    public final PrintStream getErrorStream() {
        return err;
    }
    /**
     * Returns the application input stream.
     *
     * @return The application input stream.
     */
    public final InputStream getInputStream() {
        return in;
    }
    /**
     * Returns the application output stream.
     *
     * @return The application output stream.
     */
    public final PrintStream getOutputStream() {
        return out;
    }
    /**
     * Indicates whether or not the user has requested interactive behavior. The default implementation returns
     * {@code true}.
     *
     * @return {@code true} if the user has requested interactive behavior.
     */
    public boolean isInteractive() {
        return true;
    }
    /**
     * Indicates whether or not the user has requested quiet output. The default implementation returns {@code false}.
     *
     * @return {@code true} if the user has requested quiet output.
     */
    public boolean isQuiet() {
        return false;
    }
    /**
     * Indicates whether or not the user has requested script-friendly output. The default implementation returns
     * {@code false}.
     *
     * @return {@code true} if the user has requested script-friendly output.
     */
    public boolean isScriptFriendly() {
        return false;
    }
    /**
     * Indicates whether or not the user has requested verbose output. The default implementation returns {@code false}.
     *
     * @return {@code true} if the user has requested verbose output.
     */
    public boolean isVerbose() {
        return false;
    }
    /**
     * Indicates whether or not the user has requested advanced mode.
     *
     * @return Returns <code>true</code> if the user has requested advanced mode.
     */
    public boolean isAdvancedMode() {
        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.
     */
    public boolean isMenuDrivenMode() {
        return false;
    }
    /**
     * 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).
     */
    public final void pressReturnToContinue() {
        try {
            readLineOfInput(INFO_MENU_PROMPT_RETURN_TO_CONTINUE.get());
        } catch (final ClientException e) {
            // Ignore the exception - applications don't care.
        }
    }
    /**
     * Displays a message to the error stream.
     *
     * @param msg
     *            The message.
     */
    public final void errPrint(final LocalizableMessage msg) {
        getErrStream().print(wrap(msg));
    }
    /**
     * Displays a blank line to the error stream.
     */
    public final void errPrintln() {
        getErrStream().println();
    }
    /**
     * Displays a message to the error stream.
     *
     * @param msg
     *            The message.
     */
    public final void errPrintln(final LocalizableMessage msg) {
        getErrStream().println(wrap(msg));
    }
    /**
     * 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.
     */
    public final void errPrintln(final LocalizableMessage msg, final int indent) {
        getErrStream().println(wrapText(msg, MAX_LINE_WIDTH, indent));
    }
    /**
     * Displays a message to the error stream if verbose mode is enabled.
     *
     * @param msg
     *            The verbose message.
     */
    public final void errPrintVerboseMessage(final LocalizableMessage msg) {
        if (isVerbose()) {
            getErrStream().println(wrap(msg));
        }
    }
    /**
     * Displays a message to the output stream.
     *
     * @param msg
     *            The message.
     */
    public final void print(final LocalizableMessage msg) {
        if (!isQuiet()) {
            out.print(wrap(msg));
        }
    }
    /**
     * Displays a blank line to the output stream.
     */
    public final void println() {
        if (!isQuiet()) {
            out.println();
        }
    }
    /**
     * Displays a message to the output stream.
     *
     * @param msg
     *            The message.
     */
    public final void println(final LocalizableMessage msg) {
        if (!isQuiet()) {
            out.println(wrap(msg));
        }
    }
    /**
     * Displays a message to the output stream indented by the specified number of columns.
     *
     * @param msg
     *            The message.
     * @param indent
     *            The number of columns to indent.
     */
    public final void println(final LocalizableMessage msg, final int indent) {
        if (!isQuiet()) {
            out.println(wrapText(msg, MAX_LINE_WIDTH, indent));
        }
    }
    /**
     * Prints a progress bar on the same output stream line if not in quiet mode.
     *
     * <pre>
     * Like
     *   msg......   50%
     *   if progress is up to 100 :
     *   msg.....................  100%
     *   if progress is < 0 :
     *   msg....  FAIL
     *   msg.....................  FAIL
     * </pre>
     *
     * @param linePos
     *            The progress bar starts at this position on the line.
     * @param progress
     *            The current percentage progress to print.
     */
    private final void printProgressBar(final int linePos, final int progress) {
        if (!isQuiet()) {
            final int spacesLeft = MAX_LINE_WIDTH - linePos - 10;
            StringBuilder bar = new StringBuilder();
            if (progress != 0) {
                for (int i = 0; i < PROGRESS_LINE; i++) {
                    if (i < (Math.abs(progress) * spacesLeft) / 100 && bar.length() < spacesLeft) {
                        bar.append(".");
                    }
                }
            }
            bar.append(".   ");
            if (progress >= 0) {
                bar.append(progress).append("%     ");
            } else {
                bar.append("FAIL");
                isProgressSuite = false;
            }
            final int endBuilder = linePos + bar.length();
            for (int i = 0; i < endBuilder; i++) {
                bar.append("\b");
            }
            if (progress >= 100 || progress < 0) {
                bar.append(EOL);
                isProgressSuite = false;
            }
            out.print(bar);
        }
    }
    /**
     * Prints a progress bar on the same output stream line if not in quiet mode.
     * If the line's length is upper than the limit, the message is wrapped and the progress
     * bar is affected to the last one.
     * e.g.
     * <pre>
     *   Changing matching rule for 'userCertificate' and 'caCertificate' to
     *   CertificateExactMatch...............................................   100%
     * </pre>
     *
     * @param msg
     *            The message to display before the progress line.
     * @param progress
     *            The current percentage progress to print.
     * @param indent
     *            Indentation of the message.
     */
    public final void printProgressBar(String msg, final int progress, final int indent) {
        if (!isQuiet()) {
            String msgToDisplay = wrapText(msg, PROGRESS_LINE, indent);
            if (msgToDisplay.length() > PROGRESS_LINE) {
                final String[] msgWrapped = msgToDisplay.split(LINE_SEPARATOR);
                if (!isProgressSuite) {
                    for (int pos = 0; pos < msgWrapped.length - 1; pos++) {
                        println(LocalizableMessage.raw(msgWrapped[pos]));
                    }
                    isProgressSuite = true;
                }
                msgToDisplay = msgWrapped[msgWrapped.length - 1];
            }
            print(LocalizableMessage.raw(msgToDisplay));
            printProgressBar(msgToDisplay.length(), progress);
        }
    }
    /**
     * Print a line with EOL in the output stream.
     *
     * @param msgStyle
     *            The type of formatted output desired.
     * @param msg
     *            The message to display in normal mode.
     * @param indent
     *            The indentation.
     */
    public final void println(final Style msgStyle, final LocalizableMessage msg, final int indent) {
        if (!isQuiet()) {
            switch (msgStyle) {
            case TITLE:
                out.println();
                out.println(">>>> " + wrapText(msg, MAX_LINE_WIDTH, indent));
                out.println();
                break;
            case SUBTITLE:
                out.println(wrapText(msg, MAX_LINE_WIDTH, indent));
                out.println();
                break;
            case NOTICE:
                out.println(wrapText("* " + msg, MAX_LINE_WIDTH, indent));
                break;
            case ERROR:
                out.println();
                out.println(wrapText("** " + msg, MAX_LINE_WIDTH, indent));
                out.println();
                break;
            case WARNING:
                out.println(wrapText("[!] " + msg, MAX_LINE_WIDTH, indent));
                break;
            default:
                out.println(wrapText(msg, MAX_LINE_WIDTH, indent));
                break;
            }
        }
    }
    /**
     * Displays a message to the output stream if verbose mode is enabled.
     *
     * @param msg
     *            The verbose message.
     */
    public final void printVerboseMessage(final LocalizableMessage msg) {
        if (isVerbose()) {
            out.println(wrap(msg));
        }
    }
    /**
     * 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} if
     *            there should not be a default and the user must explicitly provide a value.
     * @throws ClientException
     *             If the line of input could not be retrieved for some reason.
     * @return The string value read from the user.
     */
    public final String readInput(LocalizableMessage prompt, final String defaultValue) throws ClientException {
        return readInput(prompt, defaultValue, null);
    }
    /**
     * 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} if
     *            there should not be a default and the user must explicitly provide a value.
     * @param msgStyle
     *            The formatted style chosen.
     * @throws ClientException
     *             If the line of input could not be retrieved for some reason.
     * @return The string value read from the user.
     */
    public final String readInput(LocalizableMessage prompt, final String defaultValue, final Style msgStyle)
            throws ClientException {
        if (msgStyle != null && msgStyle == Style.TITLE) {
            println();
        }
        while (true) {
            if (defaultValue != null) {
                prompt = INFO_PROMPT_SINGLE_DEFAULT.get(prompt, defaultValue);
            }
            final String response = readLineOfInput(prompt);
            if (msgStyle != null && (msgStyle == Style.TITLE || msgStyle == Style.SUBTITLE)) {
                println();
            }
            if ("".equals(response)) {
                if (defaultValue != null) {
                    return defaultValue;
                }
                println(INFO_ERROR_EMPTY_RESPONSE.get());
            }
            return response;
        }
    }
    /**
     * Interactively reads a password from the console.
     *
     * @param prompt
     *            The password prompt.
     * @return The password.
     * @throws ClientException
     *             If the password could not be retrieved for some reason.
     */
    public final char[] readPassword(final LocalizableMessage prompt) throws ClientException {
        if (console != null) {
            if (prompt != null) {
                out.print(wrap(prompt));
                out.print(" ");
            }
            try {
                final char[] password = console.readPassword();
                if (password == null) {
                    throw new EOFException("End of input");
                }
                return password;
            } catch (final Throwable e) {
                throw ClientException.adaptInputException(e);
            }
        } else {
            // FIXME: should go direct to char[] and avoid the String.
            return readLineOfInput(prompt).toCharArray();
        }
    }
    /**
     * Reads a password from the console without echoing it to the client.
     * FIXME This method should disappear when all
     * the tools will extend to ConsoleApplication.
     *
     * @return The password as an array of characters.
     * @throws ClientException
     *             If an error occurs when reading the password.
     */
    public static char[] readPassword() throws ClientException {
        try {
            return System.console().readPassword();
        } catch (IOError e) {
            throw ClientException.adaptInputException(e);
        }
    }
    /**
     * Interactively retrieves a line of input from the console.
     *
     * @param prompt
     *            The prompt.
     * @return The line of input.
     * @throws ClientException
     *             If the line of input could not be retrieved for some reason.
     */
    public final String readLineOfInput(final LocalizableMessage prompt) throws ClientException {
        if (prompt != null) {
            out.print(wrap(prompt));
            out.print(" ");
        }
        try {
            final String s = reader.readLine();
            if (s == null) {
                throw ClientException.adaptInputException(new EOFException("End of input"));
            }
            return s;
        } catch (final IOException e) {
            throw ClientException.adaptInputException(e);
        }
    }
    /**
     * Interactively retrieves a port value from the console.
     *
     * @param prompt
     *            The port prompt.
     * @param defaultValue
     *            The port default value.
     * @return Returns the port.
     * @throws ClientException
     *             If the port could not be retrieved for some reason.
     */
    public final int readPort(LocalizableMessage prompt, final int defaultValue) throws ClientException {
        if (defaultValue != -1) {
            prompt = INFO_PROMPT_SINGLE_DEFAULT.get(prompt, defaultValue);
        }
        return readValidatedInput(prompt, Utils.portValidationCallback(defaultValue), CONFIRMATION_MAX_TRIES);
    }
    /**
     * Interactively prompts for user input and continues until valid input is provided.
     *
     * @param <T>
     *            The type of decoded user input.
     * @param prompt
     *            The interactive prompt which should be displayed on each input attempt.
     * @param validator
     *            An input validator responsible for validating and decoding the user's response.
     * @return Returns the decoded user's response.
     * @throws ClientException
     *             If an unexpected error occurred which prevented validation.
     */
    public final <T> T readValidatedInput(final LocalizableMessage prompt, final ValidationCallback<T> validator)
            throws ClientException {
        while (true) {
            final String response = readLineOfInput(prompt);
            final T value = validator.validate(this, response);
            if (value != null) {
                return value;
            }
        }
    }
    /**
     * Interactively prompts for user input and continues until valid input is provided.
     *
     * @param <T>
     *            The type of decoded user input.
     * @param prompt
     *            The interactive prompt which should be displayed on each input attempt.
     * @param validator
     *            An input validator responsible for validating and decoding the user's response.
     * @param maxTries
     *            The maximum number of tries that we can make.
     * @return Returns the decoded user's response.
     * @throws ClientException
     *             If an unexpected error occurred which prevented validation or if the maximum number of tries was
     *             reached.
     */
    public final <T> T readValidatedInput(final LocalizableMessage prompt, final ValidationCallback<T> validator,
            final int maxTries) throws ClientException {
        int nTries = 0;
        while (nTries < maxTries) {
            final String response = readLineOfInput(prompt);
            final T value = validator.validate(this, response);
            if (value != null) {
                return value;
            }
            nTries++;
        }
        throw new ClientException(ReturnCode.ERROR_USER_DATA, ERR_TRIES_LIMIT_REACHED.get(maxTries));
    }
    /**
     * Inserts line breaks into the provided buffer to wrap text at no more than the specified column width (80).
     *
     * @param msg
     *            The message to wrap.
     * @return The wrapped message.
     */
    private String wrap(final LocalizableMessage msg) {
        return wrapText(msg, MAX_LINE_WIDTH);
    }
    /**
     * Returns the error stream. Effectively, when an application is in "interactive mode" all the informations should
     * be written in the STDout.
     *
     * @return The error stream that should be used with this application.
     */
    protected PrintStream getErrStream() {
        if (isInteractive()) {
            return out;
        }
        return err;
    }
    /**
     * Commodity method that interactively confirms whether a user wishes to perform an action. If
     * the application is non-interactive, then the provided default is returned automatically. If there is an error an
     * error message is logged to the provided Logger and the default value is returned.
     *
     * @param prompt
     *            The prompt describing the action.
     * @param defaultValue
     *            The default value for the confirmation message. This will be returned if the application is
     *            non-interactive or if the user just presses return.
     * @param logger
     *            the Logger to be used to log the error message.
     * @return Returns <code>true</code> if the user wishes the action to be performed, or <code>false</code> if they
     *         refused.
     * @throws ClientException
     *             if the user did not provide valid answer after a certain number of tries
     *             (ConsoleApplication.CONFIRMATION_MAX_TRIES)
     */
    protected final boolean askConfirmation(LocalizableMessage prompt, boolean defaultValue, LocalizedLogger logger)
            throws ClientException {
        int nTries = 0;
        while (nTries < CONFIRMATION_MAX_TRIES) {
            nTries++;
            try {
                return confirmAction(prompt, defaultValue);
            } catch (ClientException ce) {
                if (ce.getMessageObject().toString().contains(ERR_CONFIRMATION_TRIES_LIMIT_REACHED.get(nTries))) {
                    throw ce;
                }
                logger.warn(LocalizableMessage.raw("Error reading input: " + ce, ce));
                // Try again...
                println();
            }
        }
        throw new ClientException(ReturnCode.ERROR_USER_DATA,
            ERR_CONFIRMATION_TRIES_LIMIT_REACHED.get(CONFIRMATION_MAX_TRIES));
    }
    /**
     * Interactively confirms whether a user wishes to perform an action.
     * If the application is non-interactive, then the provided default is returned automatically.
     *
     * @param prompt
     *            The prompt describing the action.
     * @param defaultValue
     *            The default value for the confirmation message. This will be returned if the application is
     *            non-interactive or if the user just presses return.
     * @return Returns <code>true</code> if the user wishes the action to be performed, or <code>false</code> if they
     *         refused, or if an exception occurred.
     * @throws ClientException
     *             If the user's response could not be read from the console for some reason.
     */
    public final boolean confirmAction(LocalizableMessage prompt, final boolean defaultValue) throws ClientException {
        if (!isInteractive()) {
            return defaultValue;
        }
        final LocalizableMessage yes = INFO_GENERAL_YES.get();
        final LocalizableMessage no = INFO_GENERAL_NO.get();
        final LocalizableMessage errMsg = ERR_CONSOLE_APP_CONFIRM.get(yes, no);
        prompt = INFO_MENU_PROMPT_CONFIRM.get(prompt, yes, no, defaultValue ? yes : no);
        ValidationCallback<Boolean> validator = new ValidationCallback<Boolean>() {
            @Override
            public Boolean validate(ConsoleApplication app, String input) {
                String ninput = input.toLowerCase().trim();
                if (ninput.length() == 0) {
                    return defaultValue;
                } else if (no.toString().toLowerCase().startsWith(ninput)) {
                    return false;
                } else if (yes.toString().toLowerCase().startsWith(ninput)) {
                    return true;
                } else {
                    // Try again...
                    app.println();
                    app.println(errMsg);
                    app.println();
                    return null;
                }
            }
        };
        return readValidatedInput(prompt, validator, CONFIRMATION_MAX_TRIES);
    }
    /**
     * Commodity method used to repeatedly ask the user to provide a port value.
     *
     * @param prompt
     *            the prompt message.
     * @param defaultValue
     *            the default value of the port to be proposed to the user.
     * @param logger
     *            the logger where the errors will be written.
     * @return the port value provided by the user.
     */
    protected int askPort(LocalizableMessage prompt, int defaultValue, LocalizedLogger logger) {
        while (true) {
            try {
                int port = readPort(prompt, defaultValue);
                if (port != -1) {
                    return port;
                }
            } catch (ClientException ce) {
                logger.warn(LocalizableMessage.raw("Error reading input: " + ce, ce));
            }
        }
    }
    /**
     * Prints a header in the console application.
     *
     * @param header
     *            The message to display as a header.
     */
    void printHeader(final LocalizableMessage header) {
        println();
        println();
        println(header);
        println();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java
New file
@@ -0,0 +1,32 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Documentation that supplements generated descriptions.
 */
public interface DocDescriptionSupplement {
    /**
     * Retrieves a supplement to the description intended for use in generated reference documentation.
     *
     * @return The supplement to the description for use in generated reference documentation,
     *         or LocalizableMessage.EMPTY if there is no supplement.
     */
    LocalizableMessage getDocDescriptionSupplement();
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java
New file
@@ -0,0 +1,124 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
/**
 * This class provides utility functions to help generate reference documentation.
 */
public final class DocGenerationHelper {
    /** Prevent instantiation. */
    private DocGenerationHelper() {
        // Do nothing.
    }
    /** FreeMarker template configuration. */
    private static Configuration configuration;
    /**
     * Gets a FreeMarker configuration for applying templates.
     *
     * @return              A FreeMarker configuration.
     */
    private static Configuration getConfiguration() {
        if (configuration == null) {
            configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setClassForTemplateLoading(DocGenerationHelper.class, "/templates");
            configuration.setDefaultEncoding("UTF-8");
            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
        }
        return configuration;
    }
    /**
     * Appends the String result from applying a FreeMarker template.
     *
     * @param builder       Append the result to this.
     * @param template      The name of a template file found in {@code resources/templates/}.
     * @param map           The map holding the data to use in the template.
     */
    public static void applyTemplate(StringBuilder builder, final String template, final Map<String, Object> map) {
        // FixMe: This method is public so it can be used by the SubCommandUsageHandler
        // in org.forgerock.opendj.config.dsconfig.DSConfig.
        // FreeMarker requires a configuration to find the template.
        configuration = getConfiguration();
        // FreeMarker takes the data and a Writer to process the template.
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            Writer writer = new OutputStreamWriter(outputStream)) {
            Template configurationTemplate = configuration.getTemplate(template);
            configurationTemplate.process(map, writer);
            builder.append(outputStream.toString());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    /**
     * Returns an option synopsis.
     *
     * <br>
     *
     * Note: The synopsis might contain characters that must be escaped in XML.
     *
     * @param argument  The argument option.
     * @return          A synopsis.
     */
    static String getOptionSynopsis(final Argument argument) {
        StringBuilder builder = new StringBuilder();
        final Character shortID = argument.getShortIdentifier();
        if (shortID != null) {
            builder.append("-").append(shortID.charValue());
        }
        final String longID = argument.getLongIdentifier();
        if (shortID != null && longID != null) {
            builder.append(" | ");
        }
        if (longID != null) {
            builder.append("--").append(longID);
        }
        if (argument.needsValue()) {
            builder.append(" ").append(argument.getValuePlaceholder());
        }
        return builder.toString();
    }
    /**
     * Returns true when the argument handles properties.
     *
     * @param argument  The argument.
     * @return True if the argument handles properties.
     */
    public static boolean doesHandleProperties(final Argument argument) {
        // FixMe: This method is public so it can be used by the SubCommandUsageHandler
        // in org.forgerock.opendj.config.dsconfig.DSConfig.
        final String id = argument.getLongIdentifier();
        return ("add".equals(id) || "remove".equals(id) || "reset".equals(id) || "set".equals(id));
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/FileBasedArgument.java
New file
@@ -0,0 +1,169 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.forgerock.i18n.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 no filename is provided on the command line but a default
 * value is specified programmatically 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.
 */
public final class FileBasedArgument extends Argument {
    /**
     * Returns a builder which can be used for incrementally constructing a new
     * {@link FileBasedArgument}.
     *
     * @param longIdentifier
     *         The generic long identifier that will be used to refer to this argument.
     * @return A builder to continue building the {@link FileBasedArgument}.
     */
    public static Builder builder(final String longIdentifier) {
        return new Builder(longIdentifier);
    }
    /** A fluent API for incrementally constructing {@link FileBasedArgument}. */
    public static final class Builder extends ArgumentBuilder<Builder, String, FileBasedArgument> {
        private Builder(final String longIdentifier) {
            super(longIdentifier);
        }
        @Override
        Builder getThis() {
            return this;
        }
        @Override
        public FileBasedArgument buildArgument() throws ArgumentException {
            return new FileBasedArgument(this);
        }
    }
    /** The mapping between filenames specified and the first lines read from those files. */
    private final Map<String, String> namesToValues = new LinkedHashMap<>();
    private FileBasedArgument(final Builder builder) throws ArgumentException {
        super(builder);
    }
    /**
     * 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 Map<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, longIdentifier));
                return false;
            }
        } catch (final Exception e) {
            invalidReason.append(ERR_FILEARG_CANNOT_VERIFY_FILE_EXISTENCE.get(
                    valueString, longIdentifier, getExceptionMessage(e)));
            return false;
        }
        // Open the file, read the first line and close the file.
        String line;
        try (BufferedReader reader = new BufferedReader(new FileReader(valueFile))) {
            line = reader.readLine();
        } catch (final FileNotFoundException e) {
            invalidReason.append(ERR_FILEARG_CANNOT_OPEN_FILE.get(valueString, longIdentifier, getExceptionMessage(e)));
            return false;
        } catch (final IOException e) {
            invalidReason.append(ERR_FILEARG_CANNOT_READ_FILE.get(valueString, longIdentifier, getExceptionMessage(e)));
            return false;
        }
        // If the line read is null, then that means the file was empty.
        if (line == null) {
            invalidReason.append(ERR_FILEARG_EMPTY_FILE.get(valueString, longIdentifier));
            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/opendj-cli/src/main/java/com/forgerock/opendj/cli/HelpCallback.java
New file
@@ -0,0 +1,31 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * An interface for displaying help interactively.
 */
public interface HelpCallback {
    /**
     * Displays help to the provided application console.
     *
     * @param app
     *            The console application.
     */
    void display(ConsoleApplication app);
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/IntegerArgument.java
New file
@@ -0,0 +1,139 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2010 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
/**
 * This class defines an argument type that will only accept integer values, and
 * potentially only those in a given range.
 */
public final class IntegerArgument extends Argument {
    /**
     * Returns a builder which can be used for incrementally constructing a new
     * {@link IntegerArgument}.
     *
     * @param name
     *         The generic name that will be used to refer to this argument.
     * @return A builder to continue building the {@link IntegerArgument}.
     */
    public static Builder builder(final String name) {
        return new Builder(name);
    }
    /** A fluent API for incrementally constructing {@link IntegerArgument}. */
    public static final class Builder extends ArgumentBuilder<Builder, Integer, IntegerArgument> {
        private int lowerBound = Integer.MIN_VALUE;
        private int upperBound = Integer.MAX_VALUE;
        private Builder(final String name) {
            super(name);
        }
        @Override
        Builder getThis() {
            return this;
        }
        /**
         * Sets the lower bound of this {@link IntegerArgument}.
         *
         * @param lowerBound
         *         The lower bound value.
         * @return This builder.
         */
        public Builder lowerBound(final int lowerBound) {
            this.lowerBound = lowerBound;
            return getThis();
        }
        /**
         * Sets the range of this {@link IntegerArgument}.
         *
         * @param lowerBound
         *          The range lower bound value.
         * @param upperBound
         *          The range upper bound value.
         * @return This builder.
         */
        public Builder range(final int lowerBound, final int upperBound) {
            this.lowerBound = lowerBound;
            this.upperBound = upperBound;
            return getThis();
        }
        @Override
        public IntegerArgument buildArgument() throws ArgumentException {
            return new IntegerArgument(this, lowerBound, upperBound);
        }
    }
    /** The lower bound that will be enforced for this argument. */
    private final int lowerBound;
    /** The upper bound that will be enforced for this argument. */
    private final int upperBound;
    private IntegerArgument(final Builder builder, final int lowerBound, final int upperBound)
            throws ArgumentException {
        super(builder);
        this.lowerBound = lowerBound;
        this.upperBound = upperBound;
        if (lowerBound > upperBound) {
            final LocalizableMessage message =
                    ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND.get(builder.longIdentifier, lowerBound, upperBound);
            throw new ArgumentException(message);
        }
    }
    /**
     * 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) {
        try {
            final int intValue = Integer.parseInt(valueString);
            if (intValue < lowerBound) {
                invalidReason.append(ERR_INTARG_VALUE_BELOW_LOWER_BOUND.get(longIdentifier, intValue, lowerBound));
                return false;
            }
            if (intValue > upperBound) {
                invalidReason.append(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get(longIdentifier, intValue, upperBound));
                return false;
            }
            return true;
        } catch (final NumberFormatException e) {
            invalidReason.append(ERR_ARG_CANNOT_DECODE_AS_INT.get(valueString, longIdentifier));
            return false;
        }
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Menu.java
New file
@@ -0,0 +1,38 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * An interactive console-based menu.
 *
 * @param <T>
 *          The type of success result value(s) returned by the
 *          call-back. Use <code>Void</code> if the call-backs do
 *          not return any values.
 */
public interface Menu<T> {
    /**
     * Displays the menu and waits for the user to select a valid option. When the user selects an option, the call-back
     * associated with the option will be invoked and its result returned.
     *
     * @return Returns the result of invoking the chosen menu call-back.
     * @throws ClientException
     *             If an I/O exception occurred or if one of the menu option call-backs failed for some reason.
     */
    MenuResult<T> run() throws ClientException;
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuBuilder.java
New file
@@ -0,0 +1,701 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2007-2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.forgerock.i18n.LocalizableMessage;
/**
 * An interface for incrementally building a command-line menu.
 *
 * @param <T>
 *            The type of value returned by the call-backs. Use <code>Void</code> if the call-backs do not return a
 *            value.
 */
public final class MenuBuilder<T> {
    /**
     * A simple menu option call-back which is a composite of zero or more underlying call-backs.
     *
     * @param <T>
     *            The type of value returned by the call-back.
     */
    private static final class CompositeCallback<T> implements MenuCallback<T> {
        /** The list of underlying call-backs. */
        private final Collection<MenuCallback<T>> callbacks;
        /**
         * Creates a new composite call-back with the specified set of call-backs.
         *
         * @param callbacks
         *            The set of call-backs.
         */
        public CompositeCallback(Collection<MenuCallback<T>> callbacks) {
            this.callbacks = callbacks;
        }
        @Override
        public MenuResult<T> invoke(ConsoleApplication app) throws ClientException {
            List<T> values = new ArrayList<>();
            for (MenuCallback<T> callback : callbacks) {
                MenuResult<T> result = callback.invoke(app);
                if (!result.isSuccess()) {
                    // Throw away all the other results.
                    return result;
                }
                values.addAll(result.getValues());
            }
            return MenuResult.success(values);
        }
    }
    /**
     * Underlying menu implementation generated by this menu builder.
     *
     * @param <T>
     *            The type of value returned by the call-backs. Use <code>Void</code> if the call-backs do not return a
     *            value.
     */
    private static final class MenuImpl<T> implements Menu<T> {
        /** Indicates whether the menu will allow selection of multiple numeric options. */
        private final boolean allowMultiSelect;
        /** The application console. */
        private final ConsoleApplication app;
        /** The call-back lookup table. */
        private final Map<String, MenuCallback<T>> callbacks;
        /** The char options table builder. */
        private final TableBuilder cbuilder;
        /** The call-back for the optional default action. */
        private final MenuCallback<T> defaultCallback;
        /** The description of the optional default action. */
        private final LocalizableMessage defaultDescription;
        /** The numeric options table builder. */
        private final TableBuilder nbuilder;
        /** The table printer. */
        private final TablePrinter printer;
        /** The menu prompt. */
        private final LocalizableMessage prompt;
        /** The menu title. */
        private final LocalizableMessage title;
        /**
         * The maximum number of times we display the menu if the user provides
         * bad input (-1 for unlimited).
         */
        private int nMaxTries;
        /** Private constructor. */
        private MenuImpl(ConsoleApplication app, LocalizableMessage title, LocalizableMessage prompt,
                TableBuilder ntable, TableBuilder ctable, TablePrinter printer, Map<String, MenuCallback<T>> callbacks,
                boolean allowMultiSelect, MenuCallback<T> defaultCallback, LocalizableMessage defaultDescription,
                int nMaxTries) {
            this.app = app;
            this.title = title;
            this.prompt = prompt;
            this.nbuilder = ntable;
            this.cbuilder = ctable;
            this.printer = printer;
            this.callbacks = callbacks;
            this.allowMultiSelect = allowMultiSelect;
            this.defaultCallback = defaultCallback;
            this.defaultDescription = defaultDescription;
            this.nMaxTries = nMaxTries;
        }
        @Override
        public MenuResult<T> run() throws ClientException {
            // The validation call-back which will be used to determine the
            // action call-back.
            ValidationCallback<MenuCallback<T>> validator = new ValidationCallback<MenuCallback<T>>() {
                @Override
                public MenuCallback<T> validate(ConsoleApplication app, String input) {
                    String ninput = input.trim();
                    if (ninput.length() == 0) {
                        if (defaultCallback != null) {
                            return defaultCallback;
                        } else if (allowMultiSelect) {
                            app.println();
                            app.println(ERR_MENU_BAD_CHOICE_MULTI.get());
                            app.println();
                            return null;
                        } else {
                            app.println();
                            app.println(ERR_MENU_BAD_CHOICE_SINGLE.get());
                            app.println();
                            return null;
                        }
                    } else if (allowMultiSelect) {
                        // Use a composite call-back to collect all the results.
                        List<MenuCallback<T>> cl = new ArrayList<>();
                        for (String value : ninput.split(",")) {
                            // Make sure that there are no duplicates.
                            String nvalue = value.trim();
                            Set<String> choices = new HashSet<>();
                            if (choices.contains(nvalue)) {
                                app.println();
                                app.println(ERR_MENU_BAD_CHOICE_MULTI_DUPE.get(value));
                                app.println();
                                return null;
                            } else if (!callbacks.containsKey(nvalue)) {
                                app.println();
                                app.println(ERR_MENU_BAD_CHOICE_MULTI.get());
                                app.println();
                                return null;
                            } else {
                                cl.add(callbacks.get(nvalue));
                                choices.add(nvalue);
                            }
                        }
                        return new CompositeCallback<>(cl);
                    } else if (!callbacks.containsKey(ninput)) {
                        app.println();
                        app.println(ERR_MENU_BAD_CHOICE_SINGLE.get());
                        app.println();
                        return null;
                    } else {
                        return callbacks.get(ninput);
                    }
                }
            };
            // Determine the correct choice prompt.
            LocalizableMessage promptMsg;
            if (allowMultiSelect) {
                if (defaultDescription != null) {
                    promptMsg = INFO_MENU_PROMPT_MULTI_DEFAULT.get(defaultDescription);
                } else {
                    promptMsg = INFO_MENU_PROMPT_MULTI.get();
                }
            } else {
                if (defaultDescription != null) {
                    promptMsg = INFO_MENU_PROMPT_SINGLE_DEFAULT.get(defaultDescription);
                } else {
                    promptMsg = INFO_MENU_PROMPT_SINGLE.get();
                }
            }
            // If the user selects help then we need to loop around and
            // display the menu again.
            while (true) {
                // Display the menu.
                if (title != null) {
                    app.println(title);
                    app.println();
                }
                if (prompt != null) {
                    app.println(prompt);
                    app.println();
                }
                if (nbuilder.getTableHeight() > 0) {
                    nbuilder.print(printer);
                    app.println();
                }
                if (cbuilder.getTableHeight() > 0) {
                    TextTablePrinter cprinter = new TextTablePrinter(app.getErrorStream());
                    cprinter.setDisplayHeadings(false);
                    int sz = String.valueOf(nbuilder.getTableHeight()).length() + 1;
                    cprinter.setIndentWidth(4);
                    cprinter.setColumnWidth(0, sz);
                    cprinter.setColumnWidth(1, 0);
                    cbuilder.print(cprinter);
                    app.println();
                }
                // Get the user's choice.
                MenuCallback<T> choice;
                if (nMaxTries != -1) {
                    choice = app.readValidatedInput(promptMsg, validator, nMaxTries);
                } else {
                    choice = app.readValidatedInput(promptMsg, validator);
                }
                // Invoke the user's selected choice.
                MenuResult<T> result = choice.invoke(app);
                // Determine if the help needs to be displayed, display it and start again.
                if (!result.isAgain()) {
                    return result;
                }
                app.println();
                app.println();
            }
        }
    }
    /**
     * A simple menu option call-back which does nothing but return the provided menu result.
     *
     * @param <T>
     *            The type of result returned by the call-back.
     */
    private static final class ResultCallback<T> implements MenuCallback<T> {
        /** The result to be returned by this call-back. */
        private final MenuResult<T> result;
        /** Private constructor. */
        private ResultCallback(MenuResult<T> result) {
            this.result = result;
        }
        @Override
        public MenuResult<T> invoke(ConsoleApplication app) throws ClientException {
            return result;
        }
        @Override
        public String toString() {
            return getClass().getSimpleName() + "(result=" + result + ")";
        }
    }
    /** The multiple column display threshold. */
    private int threshold = -1;
    /** Indicates whether the menu will allow selection of multiple numeric options. */
    private boolean allowMultiSelect;
    /** The application console. */
    private final ConsoleApplication app;
    /** The char option call-backs. */
    private final List<MenuCallback<T>> charCallbacks = new ArrayList<>();
    /** The char option keys (must be single-character messages). */
    private final List<LocalizableMessage> charKeys = new ArrayList<>();
    /** The synopsis of char options. */
    private final List<LocalizableMessage> charSynopsis = new ArrayList<>();
    /** Optional column headings. */
    private final List<LocalizableMessage> columnHeadings = new ArrayList<>();
    /** Optional column widths. */
    private final List<Integer> columnWidths = new ArrayList<>();
    /** The call-back for the optional default action. */
    private MenuCallback<T> defaultCallback;
    /** The description of the optional default action. */
    private LocalizableMessage defaultDescription;
    /** The numeric option call-backs. */
    private final List<MenuCallback<T>> numericCallbacks = new ArrayList<>();
    /** The numeric option fields. */
    private final List<List<LocalizableMessage>> numericFields = new ArrayList<>();
    /** The menu title. */
    private LocalizableMessage title;
    /** The menu prompt. */
    private LocalizableMessage prompt;
    /**
     * The maximum number of times that we allow the user to provide an invalid
     * answer (-1 if unlimited).
     */
    private int nMaxTries = -1;
    /**
     * Creates a new menu.
     *
     * @param app
     *            The application console.
     */
    public MenuBuilder(ConsoleApplication app) {
        this.app = app;
    }
    /**
     * Creates a "back" menu option. When invoked, this option will return a {@code MenuResult.cancel()} result.
     *
     * @param isDefault
     *            Indicates whether this option should be made the menu default.
     */
    public void addBackOption(boolean isDefault) {
        addCharOption(INFO_MENU_OPTION_BACK_KEY.get(), INFO_MENU_OPTION_BACK.get(), MenuResult.<T> cancel());
        if (isDefault) {
            setDefault(INFO_MENU_OPTION_BACK_KEY.get(), MenuResult.<T> cancel());
        }
    }
    /**
     * Creates a "cancel" menu option. When invoked, this option will return a {@code MenuResult.cancel()} result.
     *
     * @param isDefault
     *            Indicates whether this option should be made the menu default.
     */
    public void addCancelOption(boolean isDefault) {
        addCharOption(INFO_MENU_OPTION_CANCEL_KEY.get(), INFO_MENU_OPTION_CANCEL.get(), MenuResult.<T> cancel());
        if (isDefault) {
            setDefault(INFO_MENU_OPTION_CANCEL_KEY.get(), MenuResult.<T> cancel());
        }
    }
    /**
     * Adds a menu choice to the menu which will have a single letter as its key.
     *
     * @param c
     *            The single-letter message which will be used as the key for this option.
     * @param description
     *            The menu option description.
     * @param callback
     *            The call-back associated with this option.
     */
    public void addCharOption(LocalizableMessage c, LocalizableMessage description, MenuCallback<T> callback) {
        charKeys.add(c);
        charSynopsis.add(description);
        charCallbacks.add(callback);
    }
    /**
     * Adds a menu choice to the menu which will have a single letter as its key and which returns the provided result.
     *
     * @param c
     *            The single-letter message which will be used as the key for this option.
     * @param description
     *            The menu option description.
     * @param result
     *            The menu result which should be returned by this menu choice.
     */
    public void addCharOption(LocalizableMessage c, LocalizableMessage description, MenuResult<T> result) {
        addCharOption(c, description, new ResultCallback<T>(result));
    }
    /**
     * Creates a "help" menu option which will use the provided help call-back to display help relating to the other
     * menu options. When the help menu option is selected help will be displayed and then the user will be shown the
     * menu again and prompted to enter a choice.
     *
     * @param callback
     *            The help call-back.
     */
    public void addHelpOption(final HelpCallback callback) {
        MenuCallback<T> wrapper = new MenuCallback<T>() {
            @Override
            public MenuResult<T> invoke(ConsoleApplication app) throws ClientException {
                app.println();
                callback.display(app);
                return MenuResult.again();
            }
        };
        addCharOption(INFO_MENU_OPTION_HELP_KEY.get(), INFO_MENU_OPTION_HELP.get(), wrapper);
    }
    /**
     * Adds a menu choice to the menu which will have a numeric key.
     *
     * @param description
     *            The menu option description.
     * @param callback
     *            The call-back associated with this option.
     * @param extraFields
     *            Any additional fields associated with this menu option.
     * @return Returns the number associated with menu choice.
     */
    public int addNumberedOption(LocalizableMessage description, MenuCallback<T> callback,
            LocalizableMessage... extraFields) {
        List<LocalizableMessage> fields = new ArrayList<>();
        fields.add(description);
        if (extraFields != null) {
            fields.addAll(Arrays.asList(extraFields));
        }
        numericFields.add(fields);
        numericCallbacks.add(callback);
        return numericCallbacks.size();
    }
    /**
     * Adds a menu choice to the menu which will have a numeric key and which returns the provided result.
     *
     * @param description
     *            The menu option description.
     * @param result
     *            The menu result which should be returned by this menu choice.
     * @param extraFields
     *            Any additional fields associated with this menu option.
     * @return Returns the number associated with menu choice.
     */
    public int addNumberedOption(LocalizableMessage description, MenuResult<T> result,
            LocalizableMessage... extraFields) {
        return addNumberedOption(description, new ResultCallback<T>(result), extraFields);
    }
    /**
     * Creates a "quit" menu option. When invoked, this option will return a {@code MenuResult.quit()} result.
     */
    public void addQuitOption() {
        addCharOption(INFO_MENU_OPTION_QUIT_KEY.get(), INFO_MENU_OPTION_QUIT.get(), MenuResult.<T> quit());
    }
    /**
     * Sets the flag which indicates whether or not the menu will permit multiple numeric options to be selected at
     * once. Users specify multiple choices by separating them with a comma. The default is <code>false</code>.
     *
     * @param allowMultiSelect
     *            Indicates whether or not the menu will permit multiple numeric options to be selected at once.
     */
    public void setAllowMultiSelect(boolean allowMultiSelect) {
        this.allowMultiSelect = allowMultiSelect;
    }
    /**
     * Sets the optional column headings. The column headings will be displayed above the menu options.
     *
     * @param headings
     *            The optional column headings.
     */
    public void setColumnHeadings(LocalizableMessage... headings) {
        this.columnHeadings.clear();
        if (headings != null) {
            this.columnHeadings.addAll(Arrays.asList(headings));
        }
    }
    /**
     * Sets the optional column widths. A value of zero indicates that the column should be expandable, a value of
     * <code>null</code> indicates that the column should use its default width.
     *
     * @param widths
     *            The optional column widths.
     */
    public void setColumnWidths(Integer... widths) {
        this.columnWidths.clear();
        if (widths != null) {
            this.columnWidths.addAll(Arrays.asList(widths));
        }
    }
    /**
     * Sets the optional default action for this menu. The default action call-back will be invoked if the user does not
     * specify an option and just presses enter.
     *
     * @param description
     *            A short description of the default action.
     * @param callback
     *            The call-back associated with the default action.
     */
    public void setDefault(LocalizableMessage description, MenuCallback<T> callback) {
        defaultCallback = callback;
        defaultDescription = description;
    }
    /**
     * Sets the optional default action for this menu. The default action call-back will be invoked if the user does not
     * specify an option and just presses enter.
     *
     * @param description
     *            A short description of the default action.
     * @param result
     *            The menu result which should be returned by default.
     */
    public void setDefault(LocalizableMessage description, MenuResult<T> result) {
        setDefault(description, new ResultCallback<T>(result));
    }
    /**
     * Sets the number of numeric options required to trigger multiple-column display. A negative value (the default)
     * indicates that the numeric options will always be displayed in a single column. A value of 0 indicates that
     * numeric options will always be displayed in multiple columns.
     *
     * @param threshold
     *            The number of numeric options required to trigger multiple-column display.
     */
    public void setMultipleColumnThreshold(int threshold) {
        this.threshold = threshold;
    }
    /**
     * Sets the optional menu prompt. The prompt will be displayed above the menu. Menus do not have a prompt by
     * default.
     *
     * @param prompt
     *            The menu prompt, or <code>null</code> if there is not prompt.
     */
    public void setPrompt(LocalizableMessage prompt) {
        this.prompt = prompt;
    }
    /**
     * Sets the optional menu title. The title will be displayed above the menu prompt. Menus do not have a title by
     * default.
     *
     * @param title
     *            The menu title, or <code>null</code> if there is not title.
     */
    public void setTitle(LocalizableMessage title) {
        this.title = title;
    }
    /**
     * Creates a menu from this menu builder.
     *
     * @return Returns the new menu.
     */
    public Menu<T> toMenu() {
        TableBuilder nbuilder = new TableBuilder();
        Map<String, MenuCallback<T>> callbacks = new HashMap<>();
        // Determine whether multiple columns should be used for numeric options
        boolean useMultipleColumns = threshold >= 0 && numericCallbacks.size() >= threshold;
        // Create optional column headers.
        if (!columnHeadings.isEmpty()) {
            appendHeadings(nbuilder);
            if (useMultipleColumns) {
                appendHeadings(nbuilder);
            }
        }
        // Add the numeric options first.
        int sz = numericCallbacks.size();
        int rows = sz;
        if (useMultipleColumns) {
            // Display in two columns the first column should contain half
            // the options. If there are an odd number of columns then the
            // first column should contain an additional option (e.g. if
            // there are 23 options, the first column should contain 12
            // options and the second column 11 options).
            rows /= 2;
            rows += sz % 2;
        }
        for (int i = 0, j = rows; i < rows; i++, j++) {
            nbuilder.startRow();
            appendCells(nbuilder, i);
            callbacks.put(String.valueOf(i + 1), numericCallbacks.get(i));
            // Second column.
            if (useMultipleColumns && j < sz) {
                appendCells(nbuilder, j);
                callbacks.put(String.valueOf(j + 1), numericCallbacks.get(j));
            }
        }
        // Add the char options last.
        TableBuilder cbuilder = new TableBuilder();
        for (int i = 0; i < charCallbacks.size(); i++) {
            char c = charKeys.get(i).charAt(0);
            LocalizableMessage option = INFO_MENU_CHAR_OPTION.get(c);
            cbuilder.startRow();
            cbuilder.appendCell(option);
            cbuilder.appendCell(charSynopsis.get(i));
            callbacks.put(String.valueOf(c), charCallbacks.get(i));
        }
        // Configure the table printer.
        TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
        boolean hasHeadings = !columnHeadings.isEmpty();
        printer.setDisplayHeadings(hasHeadings);
        if (hasHeadings) {
            printer.setHeadingSeparatorStartColumn(1);
        }
        printer.setIndentWidth(4);
        if (columnWidths.isEmpty()) {
            printer.setColumnWidth(1, 0);
            if (useMultipleColumns) {
                printer.setColumnWidth(3, 0);
            }
        } else {
            for (int i = 0; i < columnWidths.size(); i++) {
                Integer j = columnWidths.get(i);
                if (j != null) {
                    // Skip the option key column.
                    printer.setColumnWidth(i + 1, j);
                    if (useMultipleColumns) {
                        printer.setColumnWidth(i + 2 + columnWidths.size(), j);
                    }
                }
            }
        }
        return new MenuImpl<>(app, title, prompt, nbuilder, cbuilder, printer, callbacks, allowMultiSelect,
                defaultCallback, defaultDescription, nMaxTries);
    }
    private void appendCells(TableBuilder nbuilder, int i) {
        nbuilder.appendCell(INFO_MENU_NUMERIC_OPTION.get(i + 1));
        for (LocalizableMessage field : numericFields.get(i)) {
            if (field != null) {
                nbuilder.appendCell(field);
            } else {
                nbuilder.appendCell();
            }
        }
    }
    private void appendHeadings(TableBuilder nbuilder) {
        nbuilder.appendHeading();
        for (LocalizableMessage heading : columnHeadings) {
            if (heading != null) {
                nbuilder.appendHeading(heading);
            } else {
                nbuilder.appendHeading();
            }
        }
    }
    /**
     * Sets the maximum number of tries that the user can provide an invalid value in the menu. -1 for unlimited tries
     * (the default). If this limit is reached a ClientException will be thrown.
     *
     * @param nTries
     *            the maximum number of tries.
     */
    public void setMaxTries(int nTries) {
        nMaxTries = nTries;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuCallback.java
New file
@@ -0,0 +1,41 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * A menu call-back which should be associated with each menu option.
 * When an option is selected the call-back is invoked.
 *
 * @param <T>
 *          The type of success result value(s) returned by the
 *          call-back. Use <code>Void</code> if the call-backs do
 *          not return any values.
 */
public interface MenuCallback<T> {
   /**
    * Invoke the menu call-back.
    *
    * @param app
    *          The application console.
    * @return Returns the result of invoking the menu call-back.
    * @throws ClientException
    *           If the menu call-back fails for some reason.
    */
    MenuResult<T> invoke(ConsoleApplication app) throws ClientException;
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MenuResult.java
New file
@@ -0,0 +1,253 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
 * The result of running a {@link Menu}. The result indicates to the
 * application how it should proceed:
 * <ul>
 * <li>{@link #again()} - the menu should be displayed again. A good
 * example of this is when a user chooses to view some help. Normally,
 * after the help is displayed, the user is allowed to select another
 * option
 * <li>{@link #cancel()} - the user chose to cancel any task
 * currently in progress and go back to the previous main menu if
 * applicable
 * <li>{@link #success()} - the user chose to apply any task
 * currently in progress and go back to the previous menu if
 * applicable. Any result values applicable to the chosen option can
 * be retrieved using {@link #getValue()} or {@link #getValues()}
 * <li>{@link #quit()} - the user chose to quit the application and
 * cancel all outstanding tasks.
 * </ul>
 *
 * @param <T>
 *            The type of result value(s) contained in success results. Use <code>Void</code> if success results should
 *            not contain values.
 */
public final class MenuResult<T> {
    /** The type of result returned from the menu. */
    private static enum Type {
        /**
         * The user selected an option which did not return a result,
         * so the menu should be displayed again.
         */
        AGAIN,
        /**
         * The user did not select an option and instead
         * chose to cancel the current task.
         */
        CANCEL,
        /**
         * The user did not select an option and instead
         * chose to quit the entire application.
         */
        QUIT,
        /**
         * The user selected an option which succeeded
         * and returned one or more result values.
         */
        SUCCESS
    }
    /**
     * Creates a new menu result indicating that the menu should be displayed again. A good example of this is when a
     * user chooses to view some help. Normally, after the help is displayed, the user is allowed to select another
     * option.
     *
     * @param <T>
     *            The type of result value(s) contained in success results. Use <code>Void</code> if success results
     *            should not contain values.
     * @return Returns a new menu result indicating that the menu should be displayed again.
     */
    public static <T> MenuResult<T> again() {
        return new MenuResult<>(Type.AGAIN, Collections.<T> emptyList());
    }
    /**
     * Creates a new menu result indicating that the user chose to cancel any task currently in progress and go back to
     * the previous main menu if applicable.
     *
     * @param <T>
     *            The type of result value(s) contained in success results. Use <code>Void</code> if success results
     *            should not contain values.
     * @return Returns a new menu result indicating that the user chose to cancel any task currently in progress and go
     *         back to the previous main menu if applicable.
     */
    public static <T> MenuResult<T> cancel() {
        return new MenuResult<>(Type.CANCEL, Collections.<T> emptyList());
    }
    /**
     * Creates a new menu result indicating that the user chose to quit the application and cancel all outstanding
     * tasks.
     *
     * @param <T>
     *            The type of result value(s) contained in success results. Use <code>Void</code> if success results
     *            should not contain values.
     * @return Returns a new menu result indicating that the user chose to quit the application and cancel all
     *         outstanding tasks.
     */
    public static <T> MenuResult<T> quit() {
        return new MenuResult<>(Type.QUIT, Collections.<T> emptyList());
    }
    /**
     * Creates a new menu result indicating that the user chose to apply any task currently in progress and go back to
     * the previous menu if applicable. The menu result will not contain any result values.
     *
     * @param <T>
     *            The type of result value(s) contained in success results. Use <code>Void</code> if success results
     *            should not contain values.
     * @return Returns a new menu result indicating that the user chose to apply any task currently in progress and go
     *         back to the previous menu if applicable.The menu result will not contain any result values.
     */
    public static <T> MenuResult<T> success() {
        return success(Collections.<T> emptySet());
    }
    /**
     * Creates a new menu result indicating that the user chose to apply any task currently in progress and go back to
     * the previous menu if applicable. The menu result will contain the provided values, which can be retrieved using
     * {@link #getValue()} or {@link #getValues()}.
     *
     * @param <T>
     *            The type of the result values.
     * @param values
     *            The result values.
     * @return Returns a new menu result indicating that the user chose to apply any task currently in progress and go
     *         back to the previous menu if applicable. The menu result will contain the provided values, which can be
     *         retrieved using {@link #getValue()} or {@link #getValues()}.
     */
    public static <T> MenuResult<T> success(Collection<T> values) {
        return new MenuResult<>(Type.SUCCESS, new ArrayList<>(values));
    }
    /**
     * Creates a new menu result indicating that the user chose to apply any task currently in progress and go back to
     * the previous menu if applicable. The menu result will contain the provided value, which can be retrieved using
     * {@link #getValue()} or {@link #getValues()}.
     *
     * @param <T>
     *            The type of the result value.
     * @param value
     *            The result value.
     * @return Returns a new menu result indicating that the user chose to apply any task currently in progress and go
     *         back to the previous menu if applicable. The menu result will contain the provided value, which can be
     *         retrieved using {@link #getValue()} or {@link #getValues()}.
     */
    public static <T> MenuResult<T> success(T value) {
        return success(Collections.singleton(value));
    }
    /** The type of result returned from the menu. */
    private final Type type;
    /** The menu result value(s). */
    private final Collection<T> values;
    /** Private constructor. */
    private MenuResult(Type type, Collection<T> values) {
        this.type = type;
        this.values = values;
    }
    /**
     * Gets the menu result value if this is a menu result indicating success.
     *
     * @return Returns the menu result value, or <code>null</code> if there was no result value or if this is not a
     *         success menu result.
     * @see #isSuccess()
     */
    public T getValue() {
        if (!values.isEmpty()) {
            return values.iterator().next();
        }
        return null;
    }
    /**
     * Gets the menu result values if this is a menu result indicating success.
     *
     * @return Returns the menu result values, which may be empty if there were no result values or if this is not a
     *         success menu result.
     * @see #isSuccess()
     */
    public Collection<T> getValues() {
        return new ArrayList<>(values);
    }
    /**
     * Determines if this menu result indicates that the menu should be displayed again. A good example of this is when
     * a user chooses to view some help. Normally, after the help is displayed, the user is allowed to select another
     * option.
     *
     * @return Returns <code>true</code> if this menu result indicates that the menu should be displayed again.
     */
    public boolean isAgain() {
        return type == Type.AGAIN;
    }
    /**
     * Determines if this menu result indicates that the user chose to cancel any task currently in progress and go back
     * to the previous main menu if applicable.
     *
     * @return Returns <code>true</code> if this menu result indicates that the user chose to cancel any task currently
     *         in progress and go back to the previous main menu if applicable.
     */
    public boolean isCancel() {
        return type == Type.CANCEL;
    }
    /**
     * Determines if this menu result indicates that the user chose to quit the application and cancel all outstanding
     * tasks.
     *
     * @return Returns <code>true</code> if this menu result indicates that the user chose to quit the application and
     *         cancel all outstanding tasks.
     */
    public boolean isQuit() {
        return type == Type.QUIT;
    }
    /**
     * Determines if this menu result indicates that the user chose to apply any task currently in progress and go back
     * to the previous menu if applicable. Any result values can be retrieved using the {@link #getValue()} or
     * {@link #getValues()} methods.
     *
     * @return Returns <code>true</code> if this menu result indicates that the user chose to apply any task currently
     *         in progress and go back to the previous menu if applicable.
     * @see #getValue()
     * @see #getValues()
     */
    public boolean isSuccess() {
        return type == Type.SUCCESS;
    }
    @Override
    public String toString() {
        return getClass().getSimpleName() + "(type=" + type + ", values=" + values + ")";
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java
New file
@@ -0,0 +1,150 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.ERR_MCARG_VALUE_NOT_ALLOWED;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessageBuilder;
/**
 * This class defines an argument type that will only accept one or more of a
 * specific set of string values.
 *
 * @param <V>
 *            The type of values returned by this argument.
 */
public final class MultiChoiceArgument<V> extends Argument {
    /**
     * Returns a builder which can be used for incrementally constructing a new
     * {@link MultiChoiceArgument<V>}.
     *
     * @param <V>
     *         The type of values returned by this argument.
     * @param longIdentifier
     *         The generic long identifier that will be used to refer to this argument.
     * @return A builder to continue building the {@link MultiChoiceArgument}.
     */
    public static <V> Builder<V> builder(final String longIdentifier) {
        return new Builder<>(longIdentifier);
    }
    /** A fluent API for incrementally constructing {@link MultiChoiceArgument<V>}. */
    public static final class Builder<V> extends ArgumentBuilder<Builder<V>, V, MultiChoiceArgument<V>> {
        private final List<V> allowedValues = new LinkedList<>();
        private Builder(final String longIdentifier) {
            super(longIdentifier);
        }
        @Override
        Builder<V> getThis() {
            return this;
        }
        /**
         * Specifies the set of values that are allowed for the {@link MultiChoiceArgument<V>}.
         *
         * @param allowedValues
         *         The {@link MultiChoiceArgument<V>} allowed values.
         * @return This builder.
         */
        public Builder<V> allowedValues(final Collection<V> allowedValues) {
            this.allowedValues.addAll(allowedValues);
            return getThis();
        }
        /**
         * Specifies the set of values that are allowed for the {@link MultiChoiceArgument<V>}.
         *
         * @param allowedValues
         *         The {@link MultiChoiceArgument<V>} allowed values.
         * @return This builder.
         */
        @SuppressWarnings("unchecked")
        public final Builder<V> allowedValues(final V... allowedValues) {
            this.allowedValues.addAll(Arrays.asList(allowedValues));
            return getThis();
        }
        @Override
        public MultiChoiceArgument<V> buildArgument() throws ArgumentException {
            return new MultiChoiceArgument<>(this, allowedValues);
        }
    }
    /** The set of values that will be allowed for use with this argument. */
    private final Collection<V> allowedValues;
    private <V1> MultiChoiceArgument(final Builder<V1> builder, final Collection<V> allowedValues)
            throws ArgumentException {
        super(builder);
        this.allowedValues = allowedValues;
    }
    /**
     * Retrieves the string value 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 V getTypedValue() throws ArgumentException {
        final String v = super.getValue();
        if (v == null) {
            return null;
        }
        for (final V allowedValue : allowedValues) {
            if (allowedValue.toString().equalsIgnoreCase(v)) {
                return allowedValue;
            }
        }
        throw new IllegalStateException("This MultiChoiceArgument value is not part of the allowed values.");
    }
    /**
     * 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 V allowedValue : allowedValues) {
            if (allowedValue.toString().equalsIgnoreCase(valueString)) {
                return true;
            }
        }
        invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED.get(longIdentifier, valueString));
        return false;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiColumnPrinter.java
New file
@@ -0,0 +1,519 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2012-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.Utils.repeat;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.forgerock.util.Reject;
/**
 * Utility class for printing columns of data.
 * <p>
 * This printer can be used to print data in formatted table or in csv format.
 * <p>
 * Regarding the formatting table feature, this class allows you to specify for each {@link Column}s:
 * <ul>
 *     <li>A unique identifier</li>
 *     <li>The column title which will be printed by a call to {@link MultiColumnPrinter#printTitleLine()}</li>
 *     <li>The size (if a cell's data is bigger than the predefined size, then the data will not be truncated,
 *         i.e. it will overflow)</li>
 *     <li>The number of digits to keep (for {@link Double} data)</li>
 * </ul>
 * <p>
 * Code to write data is independent of the {@link MultiColumnPrinter} configuration:
 * <pre>
 * void printData(final MultiColumnPrinter printer) {
 *     String[][] myData = new String[][] {
 *         new String[]{"U.S.A", "34.2", "40.8", ".us"},
 *         new String[]{"United Kingdom", "261.1", "31.6", ".uk"},
 *         new String[]{"France", "98.8", "30.1", ".fr"}
 *     };
 *
 *     int i;
 *     for (String[] countryData : myData) {
 *         i = 0;
 *         for (final MultiColumnPrinter.Column column : printer.getColumns()) {
 *             printer.printData(countryData[i++]);
 *         }
 *     }
 *  }
 * </pre>
 * <p>
 * The following code sample presents how to create a {@link MultiColumnPrinter} to write CSV data:
 * <pre>
 * final List<MultiColumnPrinter.Column> columns = new ArrayList&lt;&gt;();
 * columns.add(MultiColumnPrinter.column("CountryNameColumnId", "country_name", 0));
 * columns.add(MultiColumnPrinter.column("populationDensityId", "population_density", 1));
 * columns.add(MultiColumnPrinter.column("GiniId", "gini", 1));
 * columns.add(MultiColumnPrinter.column("internetTLDId", "internet_tld", 0));
 * MultiColumnPrinter myCsvPrinter = MultiColumnPrinter.builder(System.out, columns)
 *                                                     .columnSeparator(",")
 *                                                     .build();
 * printData(myCsvPrinter);
 * </pre>
 * <p>
 * The code above would print:
 * <pre>
 * country_name,population_density,gini,internet_tld
 * U.S.A,34.2,40.8,.us
 * United Kingdom,261.1,31.6,.uk
 * France,98.8,30.1,.fr
 * </pre>
 * <p>
 * The following code sample presents how to configure a {@link MultiColumnPrinter}
 * to print the same data on console with some title headers.
 * <pre>
 *     final List<MultiColumnPrinter.Column> columns = new ArrayList&lt;&gt;();
 *     columns.add(MultiColumnPrinter.separatorColumn());
 *     columns.add(MultiColumnPrinter.column("CountryNameColumnId", "Country Name", 15, 0));
 *     columns.add(MultiColumnPrinter.column("populationDensityId", "Density", 10, 1));
 *     columns.add(MultiColumnPrinter.separatorColumn());
 *     columns.add(MultiColumnPrinter.column("GiniID", "GINI", 5, 1));
 *     columns.add(MultiColumnPrinter.column("internetTLDID", "TLD", 5, 0));
 *     columns.add(MultiColumnPrinter.separatorColumn());
 *     MultiColumnPrinter myPrinter = MultiColumnPrinter.builder(System.out, columns)
 *                                                      .format(true)
 *                                                      .columnSeparator("  ")
 *                                                      .titleAlignment(MultiColumnPrinter.Alignment.CENTER)
 *                                                      .build();
 *     myPrinter.printDashedLine();
 *     myPrinter.printTitleSection("General Information", 2);
 *     myPrinter.printTitleSection("Data", 2);
 *     myPrinter.printTitleLine();
 *     myPrinter.printDashedLine();
 *     printData(myPrinter);
 *     myPrinter.printDashedLine();
 * </pre>
 * <p>
 * The code above would print:
 * <pre>
 * --------------------------------------------------
 * |       General Information     |       Data     |
 * |     Country Name     Density  |   GINI    TLD  |
 * --------------------------------------------------
 * |            U.S.A        34.2  |   40.8    .us  |
 * |   United Kingdom       261.1  |   31.6    .uk  |
 * |           France        98.8  |   30.1    .fr  |
 * --------------------------------------------------
 * </pre>
 */
public final class MultiColumnPrinter {
    /** The data alignment. */
    public enum Alignment {
        /** Data will be left-aligned. */
        LEFT,
        /** Data will be centered. */
        CENTER,
        /** Data will be right-aligned. */
        RIGHT
    }
    private static final String SEPARATOR_ID = "separator";
    private static int separatorIdNumber;
    /**
     * Returns a new separator {@link Column}.
     * <p>
     * This kind of {@link Column} can be used to separate data sections.
     *
     * @return A new separator {@link Column}.
     */
    public static Column separatorColumn() {
        return new Column(SEPARATOR_ID + separatorIdNumber++, "", 1, 0);
    }
    /**
     * Creates a new {@link Column} with the provided arguments.
     *
     * @param id
     *      The column identifier.
     * @param title
     *      The column title.
     * @param doublePrecision
     *      The double precision used to print {@link Double} data for this column.
     *      See {@link MultiColumnPrinter#printData(Double)}.
     * @return
     *      A new Column with the provided arguments.
     */
    public static Column column(final String id, final String title, final int doublePrecision) {
        return new Column(id, title, 1, doublePrecision);
    }
    /**
     * Creates a new Column with the provided arguments.
     *
     * @param id
     *      The column identifier.
     * @param title
     *      The column title.
     * @param width
     *      The column width.
     *      This information will only be used if the associated
     *      {@link MultiColumnPrinter} is configured to apply formatting.
     *      See {@link Builder#format(boolean)}.
     * @param doublePrecision
     *      The double precision to use to print data for this column.
     * @return
     *      A new Column with the provided arguments.
     */
    public static Column column(final String id, final String title, final int width, final int doublePrecision) {
        return new Column(id, title, Math.max(width, title.length()), doublePrecision);
    }
    /**
     * This class describes a Column of data used in the {@link MultiColumnPrinter}.
     * <p>
     * A column consists in the following fields:
     * <ul>
     *     <li>An identifier for the associated data.
     *     <li>A title which is printed when {@link MultiColumnPrinter#printTitleLine()} is called.
     *     <li>A width which is the max width for this column's data.
     *         This information will only be used if the associated {@link MultiColumnPrinter}
     *         is configure to apply formatting.See {@link Builder#format(boolean)}.
     *     <li>A double precision which is the number of decimal to print for numeric data.
     *         See {@link MultiColumnPrinter#printData(Double)}.
     * </ul>
     */
    public static final class Column {
        private final String id;
        private final String title;
        private final int width;
        private final int doublePrecision;
        private Column(final String id, final String title, final int width, final int doublePrecision) {
            this.id = id;
            this.title = title;
            this.width = Math.max(width, title.length());
            this.doublePrecision = doublePrecision;
        }
        /**
         * Returns this {@link Column} identifier.
         *
         * @return This {@link Column} identifier.
         */
        public String getId() {
            return id;
        }
    }
    /**
     * Creates a new {@link Builder} to build a {@link MultiColumnPrinter}.
     *
     * @param stream
     *      The {@link PrintStream} to use to print data.
     * @param columns
     *      The {@link List} of {@link Column} data to print.
     * @return
     *      A new {@link Builder} to build a {@link MultiColumnPrinter}.
     */
    public static Builder builder(final PrintStream stream, final List<Column> columns) {
        return new Builder(stream, columns);
    }
    /** A fluent API for incrementally constructing {@link MultiColumnPrinter}. */
    public static final class Builder {
        private final PrintStream stream;
        private final List<Column> columns;
        private Alignment titleAlignment = Alignment.RIGHT;
        private String columnSeparator = " ";
        private boolean format;
        private Builder(final PrintStream stream, final List<Column> columns) {
            Reject.ifNull(stream);
            this.stream = stream;
            this.columns = columns;
        }
        /**
         * Sets whether the {@link MultiColumnPrinter} needs to apply formatting.
         * <br>
         * Default value is {@code false}.
         *
         * @param format
         *      {@code true} if the {@link MultiColumnPrinter} needs to apply formatting.
         * @return This builder.
         */
        public Builder format(final boolean format) {
            this.format = format;
            return this;
        }
        /**
         * Sets the alignment for title elements which will be printed by the {@link MultiColumnPrinter}.
         * <p>
         * This is used only if the printer is configured to
         * apply formatting, see {@link Builder#format(boolean)}.
         * <br>
         * Default value is {@link Alignment#RIGHT}.
         *
         * @param titleAlignment
         *      The title alignment.
         * @return This builder.
         */
        public Builder titleAlignment(final Alignment titleAlignment) {
            this.titleAlignment = titleAlignment;
            return this;
        }
        /**
         * Sets the sequence to use to separate column.
         * <p>
         * Default value is {@code " "}.
         *
         * @param separator
         *      The sequence {@link String}.
         * @return This builder.
         */
        public Builder columnSeparator(final String separator) {
            this.columnSeparator = separator;
            return this;
        }
        /**
         * Creates a new {@link MultiColumnPrinter} as configured in this {@link Builder}.
         *
         * @return A new {@link MultiColumnPrinter} as configured in this {@link Builder}.
         */
        public MultiColumnPrinter build() {
            return new MultiColumnPrinter(this);
        }
    }
    private final PrintStream stream;
    private final List<Column> columns;
    private final boolean format;
    private final Alignment titleAlignment;
    private final String columnSeparator;
    private List<Column> printableColumns;
    private final int lineLength;
    private Iterator<Column> columnIterator;
    private Column currentColumn;
    private MultiColumnPrinter(final Builder builder) {
        this.stream = builder.stream;
        this.columns = Collections.unmodifiableList(builder.columns);
        this.format = builder.format;
        this.columnSeparator = builder.columnSeparator;
        this.titleAlignment = builder.titleAlignment;
        this.lineLength = computeLineLength();
        resetIterator();
        computePrintableColumns();
    }
    /** Prints a dashed line. */
    public void printDashedLine() {
        startNewLineIfNeeded();
        for (int i = 0; i < lineLength; i++) {
            stream.print('-');
        }
        stream.println();
    }
    /**
     * Formats and prints the provided text data.
     * Merge the provided text over the provided number of column.
     * <p>
     * Separator columns between merged columns will not be printed.
     *
     * @param data
     *      The section title to print.
     * @param rowSpan
     *      Specifies the number of rows a cell should span.
     */
    public void printTitleSection(final String data, final int rowSpan) {
        consumeSeparatorColumn();
        int lengthToPad = 0;
        int nbColumnMerged = 0;
        while (columnIterator.hasNext() && nbColumnMerged < rowSpan) {
            lengthToPad += currentColumn.width + columnSeparator.length();
            if (!isSeparatorColumn(currentColumn)) {
                nbColumnMerged++;
            }
            currentColumn = columnIterator.next();
        }
        stream.print(align(data, titleAlignment, lengthToPad));
        consumeSeparatorColumn();
        if (!columnIterator.hasNext()) {
            nextLine();
        }
    }
    /** Prints a line with all column title and separator. */
    public void printTitleLine() {
        startNewLineIfNeeded();
        passFirstSeparatorColumn();
        for (final Column column : this.printableColumns) {
            printCell(column.title, Alignment.RIGHT);
        }
    }
    /**
     * Prints the provided {@link Double} value on the current column.
     * <p>
     * If this {@link MultiColumnPrinter} is configured to apply formatting,
     * the provided value will be truncated according to the decimal
     * precision set in the corresponding {@link Column}.
     * <br>
     * See {@link MultiColumnPrinter#column(String, String, int, int)} for more details.
     *
     * @param value
     *      The double value to print.
     */
    public void printData(final Double value) {
        passFirstSeparatorColumn();
        printData(value.isNaN() ? "-"
                                : String.format(Locale.ENGLISH, "%." + currentColumn.doublePrecision + "f", value));
    }
    /**
     * Prints the provided text data on the current column.
     *
     * @param data
     *      The text data to print.
     */
    public void printData(final String data) {
        passFirstSeparatorColumn();
        printCell(data, Alignment.RIGHT);
    }
    /**
     * Returns the data {@link Column} list of this {@link MultiColumnPrinter}.
     * <p>
     * Separator columns are filtered out.
     *
     * @return The {@link Column} list of this {@link MultiColumnPrinter}.
     */
    public List<Column> getColumns() {
        return printableColumns;
    }
    private void printCell(final String data, final Alignment alignment) {
        String toPrint = format ? align(data, alignment, currentColumn.width) : data;
        if (columnIterator.hasNext()) {
            toPrint += columnSeparator;
        }
        stream.print(toPrint);
        nextLineOnEOLOrNextColumn();
    }
    /** Provided the provided string data according to the provided width and the provided alignment. */
    private String align(final String data, final Alignment alignment, final int width) {
        final String rawData = data.trim();
        final int padding = width - rawData.length();
        if (padding <= 0) {
            return rawData;
        }
        switch (alignment) {
        case RIGHT:
            return pad(padding, rawData, 0);
        case LEFT:
            return pad(0, rawData, padding);
        case CENTER:
            final int paddingBefore = padding / 2;
            return pad(paddingBefore, rawData, padding - paddingBefore);
        default:
            return "";
        }
    }
    private String pad(final int leftPad, final String s, final int rightPad) {
        return new StringBuilder().append(repeat(' ', leftPad))
                                  .append(s)
                                  .append(repeat(' ', rightPad))
                                  .toString();
    }
    private void passFirstSeparatorColumn() {
        if (cursorOnLineStart()) {
            consumeSeparatorColumn();
        }
    }
    private void consumeSeparatorColumn() {
        if (isSeparatorColumn(currentColumn)) {
            stream.print('|' + columnSeparator);
            nextLineOnEOLOrNextColumn();
        }
    }
    private void startNewLineIfNeeded() {
        if (!cursorOnLineStart()) {
            nextLine();
        }
    }
    private void nextLineOnEOLOrNextColumn() {
        if (columnIterator.hasNext()) {
            currentColumn = columnIterator.next();
            consumeSeparatorColumn();
        } else {
            nextLine();
        }
    }
    private void nextLine() {
        stream.println();
        resetIterator();
    }
    private void resetIterator() {
        columnIterator = columns.iterator();
        currentColumn = columnIterator.next();
    }
    private boolean cursorOnLineStart() {
        return currentColumn == columns.get(0);
    }
    private boolean isSeparatorColumn(final Column column) {
        return column.id.startsWith(SEPARATOR_ID);
    }
    private void computePrintableColumns() {
        printableColumns = new ArrayList<>(columns);
        final Iterator<Column> it = printableColumns.iterator();
        while (it.hasNext()) {
            if (isSeparatorColumn(it.next())) {
                it.remove();
            }
        }
    }
    private int computeLineLength() {
        int lineLength = 0;
        final int separatorLength = this.columnSeparator.length();
        for (final Column column : this.columns) {
            lineLength += column.width + separatorLength;
        }
        return lineLength - separatorLength;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/PromptingTrustManager.java
New file
@@ -0,0 +1,388 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008-2010 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
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 javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.util.Reject;
/**
 * A trust manager which prompts the user for the length of time that they would
 * like to trust a server certificate.
 */
public 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;
        }
    }
    private static final LocalizedLogger LOG = LocalizedLogger.getLoggerForThisClass();
    private static final String DEFAULT_PATH = System.getProperty("user.home") + File.separator
            + ".opendj" + File.separator + "keystore";
    private static final char[] DEFAULT_PASSWORD = "OpenDJ".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;
    /**
     * Creates a prompting trust manager based on these arguments.
     *
     * @param app
     *            The linked console application.
     * @param acceptedStorePath
     *            The store path.
     * @param sourceTrustManager
     *            The source of the trust manager.
     * @throws KeyStoreException
     *             If no Provider supports a KeyStoreSpi implementation for the specified type.
     * @throws IOException
     *             If there is an I/O or format problem with the keystore data, if a password is required but not given,
     *             or if the given password was incorrect. If the error is due to a wrong password, the cause of the
     *             IOException should be an UnrecoverableKeyException.
     * @throws NoSuchAlgorithmException
     *             If no provider supports a trust manager factory spi implementation for the specified algorithm.
     * @throws CertificateException
     *             If any of the certificates in the key store could not be loaded
     */
    public PromptingTrustManager(final ConsoleApplication app, final String acceptedStorePath,
            final X509TrustManager sourceTrustManager) throws KeyStoreException, IOException,
            NoSuchAlgorithmException, CertificateException {
        Reject.ifNull(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 {
            try (final FileInputStream fos = new FileInputStream(onDiskTrustStorePath)) {
                onDiskTrustStore.load(fos, DEFAULT_PASSWORD);
            }
        }
        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;
    }
    /**
     * Creates a prompting trust manager based on these arguments.
     *
     * @param app
     *            The linked console application.
     * @param sourceTrustManager
     *            The source of the trust manager.
     * @throws KeyStoreException
     *             If no Provider supports a KeyStoreSpi implementation for the specified type.
     * @throws IOException
     *             If there is an I/O or format problem with the keystore data, if a password is required but not given,
     *             or if the given password was incorrect. If the error is due to a wrong password, the cause of the
     *             IOException should be an UnrecoverableKeyException.
     * @throws NoSuchAlgorithmException
     *             If no provider supports a trust manager factory spi implementation for the specified algorithm.
     * @throws CertificateException
     *             If any of the certificates in the key store could not be loaded
     */
    public PromptingTrustManager(final ConsoleApplication app, final X509TrustManager sourceTrustManager)
            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        this(app, DEFAULT_PATH, sourceTrustManager);
    }
    @Override
    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);
                }
            }
        }
    }
    @Override
    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);
                }
            }
        }
    }
    @Override
    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.debug(LocalizableMessage.raw("Permanently accepting certificate chain to " + "truststore"));
        } else {
            LOG.debug(LocalizableMessage.raw("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.warn(LocalizableMessage.raw("Error setting certificate to store: " + e + "\nCert: " + aChain));
            }
        }
        if (permanent) {
            try {
                final File truststoreFile = new File(DEFAULT_PATH);
                if (!truststoreFile.exists()) {
                    createFile(truststoreFile);
                }
                try (final FileOutputStream fos = new FileOutputStream(truststoreFile)) {
                    onDiskTrustStore.store(fos, DEFAULT_PASSWORD);
                }
            } catch (final Exception e) {
                LOG.warn(LocalizableMessage.raw("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<>();
        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 ClientException 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;
                }
                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/opendj-cli/src/main/java/com/forgerock/opendj/cli/ReturnCode.java
New file
@@ -0,0 +1,218 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.HashMap;
import java.util.Map;
/**
 * List of return codes used by CLIs.
 */
public enum ReturnCode {
    /**
     * Successful setup.
     * <PRE>
     * Code value of 0.
     * </PRE>
     */
    SUCCESS(0),
    /**
     * Unexpected error (potential bug).
     * <PRE>
     * Code value of 1.
     * </PRE>
     */
    ERROR_UNEXPECTED(1),
    /**
     * Cannot parse arguments or data provided by user is not valid.
     * <PRE>
     * Code value of 2.
     * </PRE>
     */
    ERROR_USER_DATA(2),
    /**
     * The LDAP result code for operations that fail due to a protocol error.
     */
    PROTOCOL_ERROR(2),
    /**
     * Error server already installed.
     * <PRE>
     * Code value of 3.
     * </PRE>
     */
    ERROR_SERVER_ALREADY_INSTALLED(3),
    /**
     * Error initializing server.
     * <PRE>
     * Code value of 4.
     * </PRE>
     */
    ERROR_INITIALIZING_SERVER(4),
    /**
     * The user failed providing password (for the key store for instance).
     * <PRE>
     * Code value of 5.
     * </PRE>
     */
    ERROR_PASSWORD_LIMIT(5),
    /**
     * The user cancelled the process.
     * <PRE>
     * Code value of 6.
     * </PRE>
     */
    ERROR_USER_CANCELLED(6),
    /**
     * The user doesn't accept the license.
     * <PRE>
     * Code value of 7.
     * </PRE>
     */
    ERROR_LICENSE_NOT_ACCEPTED(7),
    /**
     * The LDAP result code for operations that fail because the requested
     * authentication method is not supported.
     */
    AUTH_METHOD_NOT_SUPPORTED(7),
    /**
     * Incompatible java version.
     * <PRE>
     * Code value of 8.
     * </PRE>
     */
    JAVA_VERSION_INCOMPATIBLE(8),
    /**
     * Application specific error.
     */
    APPLICATION_ERROR(10),
    /**
     * The LDAP result code used for multi-stage SASL bind operations that are not
     * yet complete.
     */
    SASL_BIND_IN_PROGRESS(14),
    /**
     * Conflicting command line arguments.
     */
    CONFLICTING_ARGS(18),
    /**
     * The LDAP result code for operations that fail because a defined constraint
     * has been violated.
     */
    CONSTRAINT_VIOLATION(19),
    /**
     * The LDAP result code for operations that fail because a targeted entry does
     * not exist.
     */
    NO_SUCH_OBJECT(32),
    /**
     * The LDAP result code for operations that fail because the user supplied
     * invalid credentials for an authentication attempt.
     */
    INVALID_CREDENTIALS(49),
    /**
     * The LDAP result code for operations that fail because the client does not
     * have permission to perform the requested operation.
     */
    INSUFFICIENT_ACCESS_RIGHTS(50),
    /**
     * The LDAP result code for operations that fail because the requested
     * operation would have resulted in an entry that conflicts with one that
     * already exists.
     */
    ENTRY_ALREADY_EXISTS(68),
    /**
     * The LDAP result code for use in cases in which none of the other defined
     * result codes are appropriate.
     */
    OTHER(80),
    /**
     * The client-side result code that indicates that a previously-established
     * connection to the server was lost.  This is for client-side use only and
     * should never be transferred over protocol.
     */
    CLIENT_SIDE_SERVER_DOWN(81),
    /**
     * The client-side result code that indicates that a local error occurred that
     * had nothing to do with interaction with the server.  This is for
     * client-side use only and should never be transferred over protocol.
     */
    CLIENT_SIDE_LOCAL_ERROR(82),
    /**
     * The client-side result code that indicates that an error occurred while
     * encoding a request to send to the server.  This is for client-side use only
     * and should never be transferred over protocol.
     */
    CLIENT_SIDE_ENCODING_ERROR(83),
    /**
     * The client-side result code that indicates that an error occurred while
     * decoding a response from the server.  This is for client-side use only and
     * should never be transferred over protocol.
     */
    CLIENT_SIDE_DECODING_ERROR(84),
    /**
     * The client-side result code that indicates that the user requested an
     * unknown or unsupported authentication mechanism.  This is for client-side
     * use only and should never be transferred over protocol.
     */
    CLIENT_SIDE_AUTH_UNKNOWN(86),
    /**
     * The client-side result code that indicates that there was a problem with one or more of the parameters provided
     * by the user.
     * <PRE>
     * Code value of 89.
     * </PRE>
     */
    CLIENT_SIDE_PARAM_ERROR(89),
    /**
     * The client-side result code that indicates that the client was not able to
     * establish a connection to the server.  This is for client-side use only and
     * should never be transferred over protocol.
     */
    CLIENT_SIDE_CONNECT_ERROR(91);
    private int returnCode;
    private static final Map<Integer, String> RETURNCODE = new HashMap<>();
    static {
        for (final ReturnCode rc : ReturnCode.values()) {
            RETURNCODE.put(rc.get(), rc.name());
        }
    }
    private ReturnCode(int returnCode) {
        this.returnCode = returnCode;
    }
    /**
     * Get the corresponding return code value.
     *
     * @return The corresponding return code value.
     */
    public int get() {
        return returnCode;
    }
    /**
     * Retrieves a string representation of the return code.
     *
     * @param code
     *            The code value for which to obtain the string representation.
     * @return The string representation of the return code.
     */
    public static String get(int code) {
        return RETURNCODE.get(code);
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/StringArgument.java
New file
@@ -0,0 +1,61 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import org.forgerock.i18n.LocalizableMessageBuilder;
/** This class defines an argument type that will accept any string value. */
public final class StringArgument extends Argument {
    /**
     * Returns a builder which can be used for incrementally constructing a new
     * {@link StringArgument}.
     *
     * @param name
     *         The generic name that will be used to refer to this argument.
     * @return A builder to continue building the {@link StringArgument}.
     */
    public static Builder builder(final String name) {
        return new Builder(name);
    }
    /** A fluent API for incrementally constructing {@link StringArgument}. */
    public static final class Builder extends ArgumentBuilder<Builder, String, StringArgument> {
        private Builder(final String name) {
            super(name);
        }
        @Override
        Builder getThis() {
            return this;
        }
        @Override
        public StringArgument buildArgument() throws ArgumentException {
            return new StringArgument(this);
        }
    }
    private StringArgument(final Builder builder) throws ArgumentException {
        super(builder);
    }
    @Override
    public boolean valueIsAcceptable(final String valueString, final LocalizableMessageBuilder invalidReason) {
        // All values will be acceptable for this argument.
        return true;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java
New file
@@ -0,0 +1,355 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.util.StaticUtils.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import org.forgerock.i18n.LocalizableMessage;
/**
 * This class defines a data structure for holding information about a subcommand that may be used with the subcommand
 * argument parser. The subcommand has a name, a description, and a set of arguments.
 */
public class SubCommand implements DocDescriptionSupplement {
    /** Indicates whether this subCommand should be hidden in the usage information. */
    private boolean isHidden;
    /** The mapping between the short argument IDs and the arguments for this subcommand. */
    private final HashMap<Character, Argument> shortIDMap = new HashMap<>();
    /** The mapping between the long argument IDs and the arguments for this subcommand. */
    private final HashMap<String, Argument> longIDMap = new HashMap<>();
    /** The list of arguments associated with this subcommand. */
    private final LinkedList<Argument> arguments = new LinkedList<>();
    /** The description for this subcommand. */
    private LocalizableMessage description;
    /** The name of this subcommand. */
    private String name;
    /** The argument parser with which this subcommand is associated. */
    private SubCommandArgumentParser parser;
    /**
     * Indicates whether this parser will allow additional unnamed
     * arguments at the end of the list.
     */
    private boolean allowsTrailingArguments;
    /** The maximum number of unnamed trailing arguments that may be provided. */
    private int maxTrailingArguments;
    /** The minimum number of unnamed trailing arguments that may be provided. */
    private int minTrailingArguments;
    /** The display name that will be used for the trailing arguments in the usage information. */
    private String trailingArgsDisplayName;
    /**
     * Creates a new subcommand with the provided information. The subcommand will be automatically registered with the
     * associated parser.
     *
     * @param parser
     *            The argument parser with which this subcommand is associated.
     * @param name
     *            The name of this subcommand.
     * @param description
     *            The description of this subcommand.
     * @throws ArgumentException
     *             If the associated argument parser already has a subcommand with the same name.
     */
    public SubCommand(SubCommandArgumentParser parser, String name, LocalizableMessage description)
            throws ArgumentException {
        this(parser, name, false, 0, 0, null, description);
    }
    /**
     * Creates a new subcommand with the provided information. The subcommand will be automatically registered with the
     * associated parser.
     *
     * @param parser
     *            The argument parser with which this subcommand is associated.
     * @param name
     *            The name of this subcommand.
     * @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.
     * @param description
     *            The description of this subcommand.
     * @throws ArgumentException
     *             If the associated argument parser already has a subcommand with the same name.
     */
    public SubCommand(SubCommandArgumentParser parser, String name, boolean allowsTrailingArguments,
            int minTrailingArguments, int maxTrailingArguments, String trailingArgsDisplayName,
            LocalizableMessage description) throws ArgumentException {
        this.parser = parser;
        this.name = name;
        this.description = description;
        this.allowsTrailingArguments = allowsTrailingArguments;
        this.minTrailingArguments = minTrailingArguments;
        this.maxTrailingArguments = maxTrailingArguments;
        this.trailingArgsDisplayName = trailingArgsDisplayName;
        this.isHidden = false;
        String nameToCheck = name;
        if (parser.longArgumentsCaseSensitive()) {
            nameToCheck = toLowerCase(name);
        }
        if (parser.hasSubCommand(nameToCheck)) {
            LocalizableMessage message = ERR_ARG_SUBCOMMAND_DUPLICATE_SUBCOMMAND.get(name);
            throw new ArgumentException(message);
        }
        parser.addSubCommand(this);
    }
    /**
     * Retrieves the name of this subcommand.
     *
     * @return The name of this subcommand.
     */
    public String getName() {
        return name;
    }
    /**
     * Retrieves the description for this subcommand.
     *
     * @return The description for this subcommand.
     */
    public LocalizableMessage getDescription() {
        return description;
    }
    /**
     * A supplement to the description for this subcommand
     * intended for use in generated reference documentation.
     */
    private LocalizableMessage docDescriptionSupplement;
    @Override
    public LocalizableMessage getDocDescriptionSupplement() {
        return docDescriptionSupplement != null ? docDescriptionSupplement : LocalizableMessage.EMPTY;
    }
    /**
     * Sets a supplement to the description intended for use in generated reference documentation.
     *
     * @param docDescriptionSupplement
     *            The supplement to the description for use in generated reference documentation.
     */
    public void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
        this.docDescriptionSupplement = docDescriptionSupplement;
    }
    /**
     * Retrieves the set of arguments for this subcommand.
     *
     * @return The set of arguments for this subcommand.
     */
    public LinkedList<Argument> getArguments() {
        return arguments;
    }
    /**
     * Retrieves the subcommand argument with the specified short identifier.
     *
     * @param shortID
     *            The short identifier of the argument to retrieve.
     * @return The subcommand argument with the specified short identifier, or <CODE>null</CODE> if there is none.
     */
    public Argument getArgument(Character shortID) {
        return shortIDMap.get(shortID);
    }
    /**
     * Retrieves the subcommand argument with the specified long identifier.
     *
     * @param longID
     *            The long identifier of the argument to retrieve.
     * @return The subcommand argument with the specified long identifier, or <CODE>null</CODE> if there is none.
     */
    public Argument getArgument(String longID) {
        return longIDMap.get(longID);
    }
    /**
     * Retrieves the subcommand argument with the specified long identifier.
     *
     * @param longIdentifier
     *            The long identifier of the argument to retrieve.
     * @return The subcommand argument with the specified long identifier,
     *         or <CODE>null</CODE> if there is no such argument.
     */
    public Argument getArgumentForLongIdentifier(final String longIdentifier) {
        return longIDMap.get(parser.longArgumentsCaseSensitive() ? longIdentifier : toLowerCase(longIdentifier));
    }
    /**
     * Adds the provided argument for use with this subcommand.
     *
     * @param argument
     *            The argument to add for use with this subcommand.
     * @throws ArgumentException
     *             If either the short ID or long ID for the argument conflicts with that of another argument already
     *             associated with this subcommand.
     */
    public void addArgument(Argument argument) throws ArgumentException {
        final String argumentLongID = argument.getLongIdentifier();
        if (getArgumentForLongIdentifier(argumentLongID) != null) {
            throw new ArgumentException(ERR_ARG_SUBCOMMAND_DUPLICATE_ARGUMENT_NAME.get(name, argumentLongID));
        }
        if (parser.hasGlobalArgument(argumentLongID)) {
            throw new ArgumentException(ERR_ARG_SUBCOMMAND_ARGUMENT_GLOBAL_CONFLICT.get(argumentLongID, name));
        }
        Character shortID = argument.getShortIdentifier();
        if (shortID != null) {
            if (shortIDMap.containsKey(shortID)) {
                throw new ArgumentException(ERR_ARG_SUBCOMMAND_DUPLICATE_SHORT_ID.get(
                        argumentLongID, name, String.valueOf(shortID), shortIDMap.get(shortID).getLongIdentifier()));
            }
            Argument arg = parser.getGlobalArgumentForShortID(shortID);
            if (arg != null) {
                throw new ArgumentException(ERR_ARG_SUBCOMMAND_ARGUMENT_SHORT_ID_GLOBAL_CONFLICT.get(
                        argumentLongID, name, String.valueOf(shortID), arg.getLongIdentifier()));
            }
        }
        String longID = argument.getLongIdentifier();
        if (!parser.longArgumentsCaseSensitive()) {
            longID = toLowerCase(longID);
            if (longIDMap.containsKey(longID)) {
                throw new ArgumentException(ERR_ARG_SUBCOMMAND_DUPLICATE_LONG_ID.get(argumentLongID, name));
            }
        }
        Argument arg = parser.getGlobalArgumentForLongID(longID);
        if (arg != null) {
            throw new ArgumentException(ERR_ARG_SUBCOMMAND_ARGUMENT_LONG_ID_GLOBAL_CONFLICT.get(argumentLongID, name));
        }
        arguments.add(argument);
        if (shortID != null) {
            shortIDMap.put(shortID, argument);
        }
        if (longID != null) {
            longIDMap.put(longID, argument);
        }
    }
    /**
     * Indicates whether this sub-command 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 sub-command allows unnamed trailing arguments, or <CODE>false</CODE> if it does
     *         not.
     */
    public boolean allowsTrailingArguments() {
        return allowsTrailingArguments;
    }
    /**
     * 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.
     */
    public int getMinTrailingArguments() {
        return minTrailingArguments;
    }
    /**
     * 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.
     */
    public int getMaxTrailingArguments() {
        return maxTrailingArguments;
    }
    /**
     * Retrieves the trailing arguments display name.
     *
     * @return Returns the trailing arguments display name.
     */
    public String getTrailingArgumentsDisplayName() {
        return trailingArgsDisplayName;
    }
    /**
     * 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.
     */
    public ArrayList<String> getTrailingArguments() {
        return parser.getTrailingArguments();
    }
    /**
     * Indicates whether this subcommand should be hidden from the usage information.
     *
     * @return <CODE>true</CODE> if this subcommand should be hidden from the usage information, or <CODE>false</CODE>
     *         if not.
     */
    public boolean isHidden() {
        return isHidden;
    }
    /**
     * Specifies whether this subcommand should be hidden from the usage information.
     *
     * @param isHidden
     *            Indicates whether this subcommand should be hidden from the usage information.
     */
    public void setHidden(boolean isHidden) {
        this.isHidden = isHidden;
    }
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName()).append("(").append("name=").append(this.name);
        if (!longIDMap.isEmpty()) {
            sb.append(", longIDs=").append(longIDMap.keySet());
        }
        if (!shortIDMap.isEmpty()) {
            sb.append(", shortIDs=").append(shortIDMap.keySet());
        }
        sb.append(")");
        return sb.toString();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java
New file
@@ -0,0 +1,1219 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2010 Sun Microsystems, Inc.
 * Portions Copyright 2011-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.ArgumentConstants.*;
import static com.forgerock.opendj.cli.CliMessages.*;
import static com.forgerock.opendj.cli.DocGenerationHelper.*;
import static com.forgerock.opendj.cli.Utils.*;
import static com.forgerock.opendj.util.StaticUtils.*;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.SortedMap;
import java.util.TreeMap;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import com.forgerock.opendj.util.OperatingSystem;
/**
 * This class defines a variant of the argument parser that can be used with applications that use subcommands to
 * customize their behavior and that have a different set of options per subcommand (e.g, "cvs checkout" takes different
 * options than "cvs commit"). This parser also has the ability to use global options that will always be applicable
 * regardless of the subcommand in addition to the subcommand-specific arguments. There must not be any conflicts
 * between the global options and the option for any subcommand, but it is allowed to re-use subcommand-specific options
 * for different purposes between different subcommands.
 */
public class SubCommandArgumentParser extends ArgumentParser {
    private static final String INDENT = "    ";
    private static final int COLUMN_ADJUST = OperatingSystem.isWindows() ? 1 : 0;
    /** The arguments that will be used to trigger the display of usage information for groups of sub-commands. */
    private final Map<Argument, Collection<SubCommand>> usageGroupArguments = new HashMap<>();
    /** The set of global arguments defined for this parser, referenced by short ID. */
    private final Map<Character, Argument> globalShortIDMap = new HashMap<>();
    /** The set of global arguments defined for this parser, referenced by long ID. */
    private final Map<String, Argument> globalLongIDMap = new HashMap<>();
    /** The set of global arguments defined for this parser, referenced by argument name. */
    private final Map<String, Argument> globalArgumentMap = new HashMap<>();
    /** The total set of global arguments defined for this parser. */
    private final List<Argument> globalArgumentList = new LinkedList<>();
    /** The set of subcommands defined for this parser, referenced by subcommand name. */
    private final SortedMap<String, SubCommand> subCommands = new TreeMap<>();
    /** The subcommand requested by the user as part of the command-line arguments. */
    private SubCommand subCommand;
    private SubCommandUsageHandler subCommandUsageHandler;
    /**
     * Creates a new instance of this subcommand argument parser with no 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 subcommand and long argument names should be treated in a case-sensitive manner.
     */
    public SubCommandArgumentParser(String mainClassName, LocalizableMessage toolDescription,
            boolean longArgumentsCaseSensitive) {
        super(mainClassName, toolDescription, longArgumentsCaseSensitive);
    }
    /**
     * Indicates whether this argument parser contains a global argument with the specified name.
     *
     * @param argumentName
     *            The name for which to make the determination.
     * @return <CODE>true</CODE> if a global argument exists with the specified name, or <CODE>false</CODE> if not.
     */
    public boolean hasGlobalArgument(String argumentName) {
        return globalArgumentMap.containsKey(argumentName);
    }
    /**
     * Retrieves the global argument with the specified short identifier.
     *
     * @param shortID
     *            The short identifier for the global argument to retrieve.
     * @return The global argument with the specified short identifier, or <CODE>null</CODE> if there is no such
     *         argument.
     */
    public Argument getGlobalArgumentForShortID(Character shortID) {
        return globalShortIDMap.get(shortID);
    }
    /**
     * Retrieves the global argument with the specified long identifier.
     *
     * @param longID
     *            The long identifier for the global argument to retrieve.
     * @return The global argument with the specified long identifier, or <CODE>null</CODE> if there is no such
     *         argument.
     */
    public Argument getGlobalArgumentForLongID(String longID) {
        return globalLongIDMap.get(longID);
    }
    /**
     * Indicates whether this argument parser has a subcommand with the specified name.
     *
     * @param name
     *            The subcommand name for which to make the determination.
     * @return <CODE>true</CODE> if this argument parser has a subcommand with the specified name, or <CODE>false</CODE>
     *         if it does not.
     */
    public boolean hasSubCommand(String name) {
        return subCommands.containsKey(name);
    }
    /**
     * Retrieves the subcommand with the specified name.
     *
     * @param name
     *            The name of the subcommand to retrieve.
     * @return The subcommand with the specified name, or <CODE>null</CODE> if no such subcommand is defined.
     */
    public SubCommand getSubCommand(String name) {
        return subCommands.get(name);
    }
    /**
     * Retrieves the subcommand that was selected in the set of command-line arguments.
     *
     * @return The subcommand that was selected in the set of command-line arguments, or <CODE>null</CODE> if none was
     *         selected.
     */
    public SubCommand getSubCommand() {
        return subCommand;
    }
    /**
     * Adds the provided argument to the set of global arguments handled by this parser.
     *
     * @param argument
     *            The argument to be added.
     * @throws ArgumentException
     *             If the provided argument conflicts with another global or subcommand argument that has already been
     *             defined.
     */
    public void addGlobalArgument(Argument argument) throws ArgumentException {
        addGlobalArgument(argument, null);
    }
    /**
     * 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 add to this sub command.
     * @throws ArgumentException
     *             If the provided argument conflicts with another global or subcommand argument that has already been
     *             defined.
     */
    @Override
    public void addLdapConnectionArgument(final Argument argument) throws ArgumentException {
        addGlobalArgument(argument, null);
    }
    /**
     * Adds the provided argument to the set of global 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 global or subcommand argument that has already been
     *             defined.
     */
    public void addGlobalArgument(Argument argument, ArgumentGroup group) throws ArgumentException {
        String longID = argument.getLongIdentifier();
        if (globalArgumentMap.containsKey(longID)) {
            throw new ArgumentException(ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_NAME.get(longID));
        }
        for (SubCommand s : subCommands.values()) {
            if (s.getArgumentForLongIdentifier(longID) != null) {
                throw new ArgumentException(ERR_SUBCMDPARSER_GLOBAL_ARG_NAME_SUBCMD_CONFLICT.get(
                        longID, s.getName()));
            }
        }
        Character shortID = argument.getShortIdentifier();
        if (shortID != null) {
            if (globalShortIDMap.containsKey(shortID)) {
                String conflictingLongID = globalShortIDMap.get(shortID).getLongIdentifier();
                throw new ArgumentException(ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_SHORT_ID.get(
                        shortID, longID, conflictingLongID));
            }
            for (SubCommand s : subCommands.values()) {
                if (s.getArgument(shortID) != null) {
                    String conflictingLongID = s.getArgument(shortID).getLongIdentifier();
                    throw new ArgumentException(ERR_SUBCMDPARSER_GLOBAL_ARG_SHORT_ID_CONFLICT.get(
                            shortID, longID, conflictingLongID, s.getName()));
                }
            }
        }
        if (!longArgumentsCaseSensitive()) {
            longID = toLowerCase(longID);
            if (globalLongIDMap.containsKey(longID)) {
                throw new ArgumentException(ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_LONG_ID.get(longID));
            }
        }
        for (SubCommand s : subCommands.values()) {
            if (s.getArgument(longID) != null) {
                throw new ArgumentException(ERR_SUBCMDPARSER_GLOBAL_ARG_LONG_ID_CONFLICT.get(longID, s.getName()));
            }
        }
        if (shortID != null) {
            globalShortIDMap.put(shortID, argument);
        }
        if (longID != null) {
            globalLongIDMap.put(longID, argument);
        }
        globalArgumentList.add(argument);
        if (group == null) {
            group = getStandardGroup(argument);
        }
        group.addArgument(argument);
        argumentGroups.add(group);
    }
    /**
     * Sets the provided argument as one which will automatically trigger the output of full usage information if it is
     * provided on the command line and no further argument validation will be performed.
     * <p>
     * If sub-command groups are defined using the {@link #setUsageGroupArgument(Argument, Collection)} method, then
     * this usage argument, when specified, will result in usage information being displayed which does not include
     * information on sub-commands.
     * <p>
     * Note that the caller will still need to add this argument to the parser with the
     * {@link #addGlobalArgument(Argument)} 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
     * {@link #parseArguments(String[])} to know that no further processing will be required.
     *
     * @param argument
     *            The argument whose presence should automatically trigger the display of full usage information.
     * @param outputStream
     *            The output stream to which the usage information should be written.
     */
    @Override
    public void setUsageArgument(Argument argument, OutputStream outputStream) {
        super.setUsageArgument(argument, outputStream);
        usageGroupArguments.put(argument, Collections.<SubCommand>emptySet());
    }
    /**
     * Sets the provided argument as one which will automatically trigger the output of partial usage information if it
     * is provided on the command line and no further argument validation will be performed.
     * <p>
     * Partial usage information will include a usage synopsis, a summary of each of the sub-commands listed in the
     * provided sub-commands collection, and a summary of the global options.
     * <p>
     * Note that the caller will still need to add this argument to the parser with the
     * {@link #addGlobalArgument(Argument)} 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
     * {@link #parseArguments(String[])} to know that no further processing will be required.
     *
     * @param argument
     *            The argument whose presence should automatically trigger the display of partial usage information.
     * @param subCommands
     *            The list of sub-commands which should have their usage displayed.
     */
    public void setUsageGroupArgument(Argument argument, Collection<SubCommand> subCommands) {
        usageGroupArguments.put(argument, subCommands);
    }
    /**
     * Sets the sub-command usage handler which will be used to display the usage information.
     *
     * @param subCommandUsageHandler the sub-command usage handler
     */
    public void setUsageHandler(SubCommandUsageHandler subCommandUsageHandler) {
        this.subCommandUsageHandler = subCommandUsageHandler;
    }
    /**
     * 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.
     */
    @Override
    public void parseArguments(String[] rawArguments, Properties argumentProperties) throws ArgumentException {
        this.subCommand = null;
        final ArrayList<String> trailingArguments = getTrailingArguments();
        trailingArguments.clear();
        setUsageOrVersionDisplayed(false);
        boolean inTrailingArgs = false;
        int numArguments = rawArguments.length;
        for (int i = 0; i < numArguments; i++) {
            final String arg = rawArguments[i];
            if (inTrailingArgs) {
                trailingArguments.add(arg);
                if (subCommand == null) {
                    throw new ArgumentException(ERR_ARG_SUBCOMMAND_INVALID.get());
                }
                if (subCommand.getMaxTrailingArguments() > 0
                        && trailingArguments.size() > subCommand.getMaxTrailingArguments()) {
                    throw new ArgumentException(ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS.get(
                            subCommand.getMaxTrailingArguments()));
                }
                continue;
            }
            if (arg.equals("--")) {
                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;
                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.
                    throw new ArgumentException(ERR_SUBCMDPARSER_LONG_ARG_WITHOUT_NAME.get(arg));
                } 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.
                String origArgName = argName;
                if (!longArgumentsCaseSensitive()) {
                    argName = toLowerCase(argName);
                }
                // See if the specified name references a global argument. If not, then
                // see if it references a subcommand argument.
                Argument a = globalLongIDMap.get(argName);
                if (a == null) {
                    if (subCommand != null) {
                        a = subCommand.getArgument(argName);
                    }
                    if (a == null) {
                        if (OPTION_LONG_HELP.equals(argName)) {
                            // "--help" will always be interpreted as requesting usage
                            // information.
                            writeToUsageOutputStream(getUsage());
                            return;
                        } else if (OPTION_LONG_PRODUCT_VERSION.equals(argName)) {
                            // "--version" will always be interpreted as requesting usage information.
                            printVersion();
                            return;
                        } else if (subCommand != null) {
                            // There is no such global argument.
                            throw new ArgumentException(
                                    ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID.get(origArgName));
                        } else {
                            // There is no such global or subcommand argument.
                            throw new ArgumentException(ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_LONG_ID.get(origArgName));
                        }
                    }
                }
                a.setPresent(true);
                // If this is a usage argument, then immediately stop and print
                // usage information.
                if (usageGroupArguments.containsKey(a)) {
                    getUsage(a);
                    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) {
                            throw new ArgumentException(
                                    ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get(argName));
                        }
                        argValue = rawArguments[++i];
                    }
                    LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
                    if (!a.valueIsAcceptable(argValue, invalidReason)) {
                        throw new ArgumentException(ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID.get(
                                argValue, argName, invalidReason));
                    }
                    // If the argument already has a value, then make sure it is
                    // acceptable to have more than one.
                    if (a.hasValue() && !a.isMultiValued()) {
                        throw new ArgumentException(ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_LONG_ID.get(origArgName));
                    }
                    a.addValue(argValue);
                } else if (argValue != null) {
                    throw new ArgumentException(
                            ERR_SUBCMDPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE.get(origArgName));
                }
            } else if (arg.equals("-")) {
                throw new ArgumentException(ERR_SUBCMDPARSER_INVALID_DASH_AS_ARGUMENT.get());
            } 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
                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. It may be either a
                // global argument or a subcommand-specific argument.
                Argument a = globalShortIDMap.get(argCharacter);
                if (a == null) {
                    if (subCommand == null) {
                        if (argCharacter == '?') {
                            // "-?" will always be interpreted as requesting usage.
                            writeToUsageOutputStream(getUsage());
                            if (getUsageArgument() != null) {
                                getUsageArgument().setPresent(true);
                            }
                            return;
                        } else if (argCharacter == OPTION_SHORT_PRODUCT_VERSION) {
                            // "-V" will always be interpreted as requesting
                            // version information except if it's already defined.
                            if (dashVAccepted()) {
                                printVersion();
                                return;
                            } else {
                                // -V is defined in another subcommand, so we cannot
                                // accept it as the version information argument
                                throw new ArgumentException(
                                        ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID.get(argCharacter));
                            }
                        } else {
                            // There is no such argument registered.
                            throw new ArgumentException(
                                    ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID.get(argCharacter));
                        }
                    } else {
                        a = subCommand.getArgument(argCharacter);
                        if (a == null) {
                            if (argCharacter == '?') {
                                // "-?" will always be interpreted as requesting usage.
                                writeToUsageOutputStream(getUsage());
                                return;
                            } else if (argCharacter == OPTION_SHORT_PRODUCT_VERSION) {
                                if (dashVAccepted()) {
                                    printVersion();
                                    return;
                                }
                            } else {
                                // There is no such argument registered.
                                throw new ArgumentException(
                                        ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get(argCharacter));
                            }
                        }
                    }
                }
                a.setPresent(true);
                // If this is the usage argument, then immediately stop and print
                // usage information.
                if (usageGroupArguments.containsKey(a)) {
                    getUsage(a);
                    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) {
                            throw new ArgumentException(
                                    ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID.get(argCharacter));
                        }
                        argValue = rawArguments[++i];
                    }
                    LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
                    if (!a.valueIsAcceptable(argValue, invalidReason)) {
                        throw new ArgumentException(ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID.get(argValue,
                                argCharacter, invalidReason));
                    }
                    // If the argument already has a value, then make sure it is
                    // acceptable to have more than one.
                    if (a.hasValue() && !a.isMultiValued()) {
                        throw new ArgumentException(ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get(argCharacter));
                    }
                    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.
                    int valueLength = argValue.length();
                    for (int j = 0; j < valueLength; j++) {
                        char c = argValue.charAt(j);
                        Argument b = globalShortIDMap.get(c);
                        if (b == null) {
                            if (subCommand == null) {
                                throw new ArgumentException(
                                        ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID.get(argCharacter));
                            }
                            b = subCommand.getArgument(c);
                            if (b == null) {
                                throw new ArgumentException(
                                        ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get(argCharacter));
                            }
                        }
                        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.
                            throw new ArgumentException(ERR_SUBCMDPARSER_CANT_MIX_ARGS_WITH_VALUES.get(
                                    argCharacter, argValue, c));
                        }
                        b.setPresent(true);
                        // If this is the usage argument, then immediately stop and
                        // print usage information.
                        if (usageGroupArguments.containsKey(b)) {
                            getUsage(b);
                            return;
                        }
                    }
                }
            } else if (subCommand != null) {
                // It's not a short or long identifier and the sub-command has
                // already been specified, so it must be the first trailing argument.
                if (subCommand.allowsTrailingArguments()) {
                    trailingArguments.add(arg);
                    inTrailingArgs = true;
                } else {
                    // Trailing arguments are not allowed for this sub-command.
                    throw new ArgumentException(ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg));
                }
            } else {
                // It must be the sub-command.
                String nameToCheck = arg;
                if (!longArgumentsCaseSensitive()) {
                    nameToCheck = toLowerCase(arg);
                }
                SubCommand sc = subCommands.get(nameToCheck);
                if (sc == null) {
                    throw new ArgumentException(ERR_SUBCMDPARSER_INVALID_ARGUMENT.get(arg));
                }
                subCommand = sc;
            }
        }
        // If we have a sub-command and it allows trailing arguments and
        // there is a minimum number, then make sure at least that many
        // were provided.
        if (subCommand != null) {
            int minTrailingArguments = subCommand.getMinTrailingArguments();
            if (subCommand.allowsTrailingArguments()
                    && minTrailingArguments > 0
                    && trailingArguments.size() < minTrailingArguments) {
                throw new ArgumentException(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(minTrailingArguments));
            }
        }
        // If we don't have the argumentProperties, try to load a properties file.
        if (argumentProperties == null) {
            argumentProperties = checkExternalProperties();
        }
        // Iterate through all the global arguments
        normalizeArguments(argumentProperties, globalArgumentList);
        // Iterate through all the subcommand-specific arguments
        if (subCommand != null) {
            normalizeArguments(argumentProperties, subCommand.getArguments());
        }
    }
    private boolean dashVAccepted() {
        if (globalShortIDMap.containsKey(OPTION_SHORT_PRODUCT_VERSION)) {
            return false;
        }
        for (SubCommand subCmd : subCommands.values()) {
            if (subCmd.getArgument(OPTION_SHORT_PRODUCT_VERSION) != null) {
                return false;
            }
        }
        return true;
    }
    /**
     * Appends usage information for the specified subcommand to the provided buffer.
     *
     * @param buffer
     *            The buffer to which the usage information should be appended.
     * @param subCommand
     *            The subcommand for which to display the usage information.
     */
    public void getSubCommandUsage(StringBuilder buffer, SubCommand subCommand) {
        buffer.append(getLocalizableScriptName());
        buffer.append(" ");
        buffer.append(subCommand.getName());
        buffer.append(" ").append(INFO_SUBCMDPARSER_OPTIONS.get());
        if (subCommand.allowsTrailingArguments()) {
            buffer.append(' ');
            buffer.append(subCommand.getTrailingArgumentsDisplayName());
        }
        buffer.append(EOL);
        wrap(buffer, subCommand.getDescription());
        buffer.append(EOL);
        if (!globalArgumentList.isEmpty()) {
            buffer.append(EOL);
            buffer.append(INFO_GLOBAL_OPTIONS.get());
            buffer.append(EOL);
            buffer.append("    ");
            buffer.append(INFO_GLOBAL_OPTIONS_REFERENCE.get(getScriptNameOrJava()));
            buffer.append(EOL);
        }
        if (!subCommand.getArguments().isEmpty()) {
            buffer.append(EOL);
            buffer.append(INFO_SUBCMD_OPTIONS.get());
            buffer.append(EOL);
        }
        for (Argument a : subCommand.getArguments()) {
            // If this argument is hidden, then skip it.
            if (a.isHidden()) {
                continue;
            }
            printLineForShortLongArgument(a, buffer);
            indentAndWrap(buffer, INDENT, a.getDescription());
            if (a.needsValue() && a.getDefaultValue() != null && a.getDefaultValue().length() > 0) {
                indentAndWrap(buffer, INDENT, INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()));
            }
        }
    }
    /**
     * Retrieves a string containing usage information based on the defined arguments.
     *
     * @return A string containing usage information based on the defined arguments.
     */
    @Override
    public String getUsage() {
        setUsageOrVersionDisplayed(true);
        final StringBuilder buffer = new StringBuilder();
        if (subCommand == null) {
            if (System.getProperty("org.forgerock.opendj.gendoc") != null) {
                generateReferenceDoc(buffer, subCommands.values());
            } else if (usageGroupArguments.size() > 1) {
                // We have sub-command groups, so don't display any
                // sub-commands by default.
                getFullUsage(Collections.<SubCommand> emptySet(), true, buffer);
            } else {
                // No grouping, so display all sub-commands.
                getFullUsage(subCommands.values(), true, buffer);
            }
        } else {
            getSubCommandUsage(buffer, subCommand);
        }
        return buffer.toString();
    }
    /**
     * Adds the provided subcommand to this argument parser. This is only intended for use by the
     * <CODE>SubCommand</CODE> constructor and does not do any validation of its own to ensure that there are no
     * conflicts with the subcommand or any of its arguments.
     *
     * @param subCommand
     *            The subcommand to add to this argument parser.
     */
    void addSubCommand(SubCommand subCommand) {
        subCommands.put(toLowerCase(subCommand.getName()), subCommand);
    }
    /** Get usage for a specific usage argument. */
    private void getUsage(Argument a) {
        setUsageOrVersionDisplayed(true);
        final StringBuilder buffer = new StringBuilder();
        final boolean isUsageArgument = isUsageArgument(a);
        if (isUsageArgument && subCommand != null) {
            getSubCommandUsage(buffer, subCommand);
        } else if (isUsageArgument && usageGroupArguments.size() <= 1) {
            // No groups - so display all sub-commands.
            getFullUsage(subCommands.values(), true, buffer);
        } else if (isUsageArgument) {
            // Using groups - so display all sub-commands group help.
            getFullUsage(Collections.<SubCommand> emptySet(), true, buffer);
        } else {
            // Requested help on specific group - don't display global options.
            getFullUsage(usageGroupArguments.get(a), false, buffer);
        }
        writeToUsageOutputStream(buffer);
    }
    /** Appends complete usage information for the specified set of sub-commands. */
    private void getFullUsage(Collection<SubCommand> c, boolean showGlobalOptions, StringBuilder buffer) {
        final LocalizableMessage toolDescription = getToolDescription();
        if (toolDescription != null && toolDescription.length() > 0) {
            buffer.append(wrapText(toolDescription, MAX_LINE_WIDTH - 1));
            buffer.append(EOL).append(EOL);
        }
        buffer.append(INFO_ARGPARSER_USAGE.get());
        buffer.append("  ");
        buffer.append(getScriptNameOrJava());
        if (subCommands.isEmpty()) {
            buffer.append(" ").append(INFO_SUBCMDPARSER_OPTIONS.get());
        } else {
            buffer.append(" ").append(INFO_SUBCMDPARSER_SUBCMD_AND_OPTIONS.get());
        }
        if (!subCommands.isEmpty()) {
            buffer.append(EOL);
            buffer.append(EOL);
            if (c.isEmpty()) {
                buffer.append(INFO_SUBCMDPARSER_SUBCMD_HELP_HEADING.get());
            } else {
                buffer.append(INFO_SUBCMDPARSER_SUBCMD_HEADING.get());
            }
            buffer.append(EOL);
        }
        if (c.isEmpty()) {
            // Display usage arguments (except the default one).
            for (Argument a : globalArgumentList) {
                if (a.isHidden()) {
                    continue;
                }
                if (usageGroupArguments.containsKey(a) && !isUsageArgument(a)) {
                    printArgumentUsage(a, buffer);
                }
            }
        } else {
            boolean isFirst = true;
            for (SubCommand sc : c) {
                if (sc.isHidden()) {
                    continue;
                }
                if (isFirst) {
                    buffer.append(EOL);
                }
                buffer.append(sc.getName());
                buffer.append(EOL);
                indentAndWrap(buffer, INDENT, sc.getDescription());
                buffer.append(EOL);
                isFirst = false;
            }
        }
        buffer.append(EOL);
        if (showGlobalOptions) {
            if (subCommands.isEmpty()) {
                buffer.append(INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get());
            } else {
                buffer.append(INFO_SUBCMDPARSER_GLOBAL_HEADING.get());
            }
            buffer.append(EOL).append(EOL);
            boolean printGroupHeaders = printUsageGroupHeaders();
            // Display non-usage arguments.
            for (ArgumentGroup argGroup : argumentGroups) {
                if (argGroup.containsArguments() && printGroupHeaders) {
                    // Print the groups description if any
                    LocalizableMessage groupDesc = argGroup.getDescription();
                    if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc)) {
                        buffer.append(EOL);
                        buffer.append(wrapText(groupDesc.toString(), MAX_LINE_WIDTH - 1));
                        buffer.append(EOL).append(EOL);
                    }
                }
                for (Argument a : argGroup.getArguments()) {
                    if (a.isHidden()) {
                        continue;
                    }
                    if (!usageGroupArguments.containsKey(a)) {
                        printArgumentUsage(a, buffer);
                    }
                }
            }
            // Finally print default usage argument.
            final Argument usageArgument = getUsageArgument();
            if (usageArgument != null) {
                printArgumentUsage(usageArgument, buffer);
            } else {
                buffer.append("-?");
            }
            buffer.append(EOL);
        }
    }
    /**
     * 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(Argument a, StringBuilder buffer) {
        String value;
        if (a.needsValue()) {
            LocalizableMessage pHolder = a.getValuePlaceholder();
            if (pHolder != null) {
                value = " " + pHolder;
            } else {
                value = " {value}";
            }
        } else {
            value = "";
        }
        final Argument usageArgument = getUsageArgument();
        Character shortIDChar = a.getShortIdentifier();
        if (shortIDChar != null) {
            if (a.equals(usageArgument)) {
                buffer.append("-?, ");
            }
            buffer.append("-");
            buffer.append(shortIDChar);
            String longIDString = a.getLongIdentifier();
            if (longIDString != null) {
                buffer.append(", --");
                buffer.append(longIDString);
            }
            buffer.append(value);
        } else {
            String longIDString = a.getLongIdentifier();
            if (longIDString != null) {
                if (a.equals(usageArgument)) {
                    buffer.append("-?, ");
                }
                buffer.append("--");
                buffer.append(longIDString);
                buffer.append(value);
            }
        }
        buffer.append(EOL);
        indentAndWrap(buffer, INDENT, a.getDescription());
        if (a.needsValue() && a.getDefaultValue() != null && a.getDefaultValue().length() > 0) {
            indentAndWrap(buffer, INDENT, INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()));
        }
    }
    /** Wraps long lines without indentation. */
    private void wrap(StringBuilder buffer, LocalizableMessage text) {
        indentAndWrap(buffer, "", text);
    }
    /**
     * 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.
     * <p>
     * FIXME consider merging with com.forgerock.opendj.cli.Utils#wrapText(String, int, int)
     */
    private void indentAndWrap(StringBuilder buffer, String indent, LocalizableMessage text) {
        int actualSize = MAX_LINE_WIDTH - indent.length() - COLUMN_ADJUST;
        indentAndWrap(indent, buffer, actualSize, text);
    }
    static void indentAndWrap(String indent, StringBuilder buffer, int actualSize, LocalizableMessage text) {
        if (text.length() <= actualSize) {
            buffer.append(indent);
            buffer.append(text);
            buffer.append(EOL);
        } else {
            String s = text.toString();
            while (s.length() > actualSize) {
                int spacePos = s.lastIndexOf(' ', actualSize);
                if (spacePos == -1) {
                    // There are no spaces in the first actualSize -1 columns.
                    // See if there is one after that point.
                    // If so, then break there. If not, then don't break at all.
                    spacePos = s.indexOf(' ');
                }
                if (spacePos == -1) {
                    buffer.append(indent).append(s).append(EOL);
                    return;
                }
                buffer.append(indent);
                buffer.append(s.substring(0, spacePos).trim());
                s = s.substring(spacePos + 1).trim();
                buffer.append(EOL);
            }
            if (s.length() > 0) {
                buffer.append(indent).append(s).append(EOL);
            }
        }
    }
    /**
     * Appends a generated DocBook XML RefEntry element for this command to the StringBuilder.
     *
     * @param builder       Append the RefEntry element to this.
     * @param subCommands   SubCommands containing reference information.
     */
    private void generateReferenceDoc(final StringBuilder builder, Collection<SubCommand> subCommands) {
        toRefEntry(builder, subCommands);
    }
    @Override
    String getSynopsisArgs() {
        if (subCommands.isEmpty()) {
            return INFO_SUBCMDPARSER_OPTIONS.get().toString();
        } else {
            return INFO_SUBCMDPARSER_SUBCMD_AND_OPTIONS.get().toString();
        }
    }
    /**
     * Appends one or more generated DocBook XML RefEntry elements (man pages) to the StringBuilder.
     * <br>
     * If the result contains more than one RefEntry,
     * then the RefEntry elements are separated with a marker:
     * {@code @@@scriptName + "-" + subCommand.getName() + @@@}.
     *
     * @param builder       Append the RefEntry element to this.
     * @param subCommands   Collection of subcommands for this tool.
     */
    void toRefEntry(StringBuilder builder, Collection<SubCommand> subCommands) {
        final String scriptName = getScriptName();
        if (scriptName == null) {
            throw new RuntimeException("The script name should have been set via the environment property '"
                    + PROPERTY_SCRIPT_NAME + "'.");
        }
        // Model for a FreeMarker template.
        Map<String, Object> map = new HashMap<>();
        map.put("locale", Locale.getDefault().getLanguage());
        map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
        map.put("name", scriptName);
        map.put("shortDesc", getShortToolDescription());
        map.put("descTitle", REF_TITLE_DESCRIPTION.get());
        map.put("args", getSynopsisArgs());
        map.put("description", eolToNewPara(getToolDescription()));
        map.put("info", getDocToolDescriptionSupplement());
        if (!globalArgumentList.isEmpty()) {
            map.put("optionSection", getOptionsRefSect1(scriptName));
        }
        map.put("subcommands", toRefSect1(scriptName, subCommands));
        map.put("trailingSectionString", System.getProperty("org.forgerock.opendj.gendoc.trailing"));
        applyTemplate(builder, "refEntry.ftl", map);
        // For dsconfig, generate one page per subcommand.
        if (scriptName.equals("dsconfig")) {
            appendSubCommandPages(builder, scriptName, subCommands);
        }
    }
    /**
     * Returns a generated DocBook XML RefSect1 element for all subcommands.
     * @param scriptName    The name of this script.
     * @param subCommands   The SubCommands containing the reference information.
     * @return              The RefSect1 element as a String.
     */
    private String toRefSect1(String scriptName, Collection<SubCommand> subCommands) {
        if (subCommands.isEmpty()) {
            return "";
        }
        Map<String, Object> map = new HashMap<>();
        map.put("name", scriptName);
        map.put("title", REF_TITLE_SUBCOMMANDS.get());
        map.put("info", getDocSubcommandsDescriptionSupplement());
        map.put("intro", REF_INTRO_SUBCOMMANDS.get(scriptName));
        if (scriptName.equals("dsconfig")) {
            // Break dsconfig into multiple pages, so use only the list here.
            map.put("isItemizedList", true);
        }
        List<String> scUsageList = new ArrayList<>();
        for (SubCommand subCommand : subCommands) {
            if (subCommand.isHidden()) {
                continue;
            }
            if (scriptName.equals("dsconfig")) {
                scUsageList.add(getSubCommandListItem(scriptName, subCommand));
            } else {
                scUsageList.add(toRefSect2(scriptName, subCommand));
            }
        }
        map.put("subcommands", scUsageList);
        StringBuilder sb = new StringBuilder();
        applyTemplate(sb, "refSect1.ftl", map);
        return sb.toString();
    }
    /**
     * Returns a DocBook XML ListItem element linking to the subcommand page.
     * @param scriptName    The name of this script.
     * @param subCommand    The SubCommand to reference.
     * @return A DocBook XML ListItem element linking to the subcommand page.
     */
    private String getSubCommandListItem(String scriptName, SubCommand subCommand) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", scriptName + "-" + subCommand.getName());
        map.put("name", scriptName + " " + subCommand.getName());
        map.put("description", eolToNewPara(subCommand.getDescription()));
        StringBuilder sb = new StringBuilder();
        applyTemplate(sb, "dscfgListItem.ftl", map);
        return sb.toString();
    }
    /**
     * Returns a generated DocBook XML RefSect2 element for a single subcommand to the StringBuilder.
     *
     * @param scriptName    The name of this script.
     * @param subCommand    The SubCommand containing reference information.
     * @return    The RefSect2 element as a String.
     */
    private String toRefSect2(String scriptName, SubCommand subCommand) {
        // Model for a FreeMarker template.
        Map<String, Object> map = new HashMap<>();
        map.put("id", scriptName + "-" + subCommand.getName());
        final String name = scriptName + " " + subCommand.getName();
        map.put("name", name);
        map.put("description", eolToNewPara(subCommand.getDescription()));
        map.put("optionsTitle", REF_TITLE_OPTIONS.get());
        map.put("optionsIntro", REF_INTRO_OPTIONS.get(name));
        // If there is a supplement to the description for this subcommand,
        // then it is already DocBook XML, so use it as is.
        map.put("info", subCommand.getDocDescriptionSupplement());
        setSubCommandOptionsInfo(map, subCommand);
        StringBuilder sb = new StringBuilder();
        applyTemplate(sb, "refSect2.ftl", map);
        return sb.toString();
    }
    /**
     * Sets information for the subcommand options in the map.
     * <br>
     * The map is expected to be used in a FreeMarker template to generate docs.
     *
     * @param map           The map in which to set the information.
     * @param subCommand    The subcommand containing the information.
     */
    private void setSubCommandOptionsInfo(Map<String, Object> map, SubCommand subCommand) {
        if (!subCommand.getArguments().isEmpty()) {
            List<Map<String, Object>> options = new LinkedList<>();
            String nameOption = null;
            for (Argument a : subCommand.getArguments()) {
                if (a.isHidden()) {
                    continue;
                }
                Map<String, Object> option = new HashMap<>();
                String optionSynopsis = getOptionSynopsis(a);
                option.put("synopsis", optionSynopsis);
                option.put("description", eolToNewPara(a.getDescription()));
                Map<String, Object> info = new HashMap<>();
                if (subCommandUsageHandler != null) {
                    if (!doesHandleProperties(a)) {
                        nameOption = "<option>" + optionSynopsis + "</option>";
                    }
                    // Let this build its own arbitrarily formatted additional info.
                    info.put("usage", subCommandUsageHandler.getArgumentAdditionalInfo(subCommand, a, nameOption));
                } else {
                    // Return a generic FQDN for localhost as the default hostname in reference documentation.
                    final String defaultValue = isHostNameArgument(a) ? "localhost.localdomain" : a.getDefaultValue();
                    info.put("default", defaultValue != null ? REF_DEFAULT.get(defaultValue) : null);
                    // If there is a supplement to the description for this argument,
                    // then it is already DocBook XML, so use it as is.
                    info.put("doc", a.getDocDescriptionSupplement());
                }
                option.put("info", info);
                options.add(option);
            }
            map.put("options", options);
        }
        if (subCommandUsageHandler != null) {
            map.put("propertiesInfo", subCommandUsageHandler.getProperties(subCommand));
        }
    }
    /**
     * Appends a generated DocBook XML RefEntry element for each subcommand to the StringBuilder.
     * <br>
     * The RefEntry elements are separated with a marker:
     * {@code @@@scriptName + "-" + subCommand.getName() + @@@}.
     *
     * @param builder       Append the RefEntry elements to this.
     * @param scriptName    The name of the tool with subcommands.
     * @param subCommands   SubCommands containing reference information.
     */
    private void appendSubCommandPages(StringBuilder builder, String scriptName, Collection<SubCommand> subCommands) {
        for (SubCommand subCommand : subCommands) {
            if (subCommand.isHidden()) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("marker", "@@@" + scriptName + "-" + subCommand.getName() + "@@@");
            map.put("locale", Locale.getDefault().getLanguage());
            map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
            map.put("id", scriptName + "-" + subCommand.getName());
            map.put("name", scriptName + " " + subCommand.getName());
            map.put("purpose", eolToNewPara(subCommand.getDescription()));
            map.put("args", INFO_SUBCMDPARSER_OPTIONS.get());
            map.put("descTitle", REF_TITLE_DESCRIPTION.get());
            map.put("description", eolToNewPara(subCommand.getDescription()));
            map.put("info", subCommand.getDocDescriptionSupplement());
            map.put("optionsTitle", REF_TITLE_OPTIONS.get());
            map.put("optionsIntro", REF_INTRO_OPTIONS.get(scriptName + " " + subCommand.getName()));
            setSubCommandOptionsInfo(map, subCommand);
            applyTemplate(builder, "dscfgSubcommand.ftl", map);
        }
        appendSubCommandReference(builder, scriptName, subCommands);
    }
    /**
     * Appends a generated DocBook XML Reference element XIncluding subcommands.
     *
     * @param builder       Append the Reference element to this.
     * @param scriptName    The name of the tool with subcommands.
     * @param subCommands   SubCommands containing reference information.
     */
    private void appendSubCommandReference(StringBuilder builder,
                                           String scriptName,
                                           Collection<SubCommand> subCommands) {
        Map<String, Object> map = new HashMap<>();
        map.put("marker", "@@@" + scriptName + "-subcommands-ref" + "@@@");
        map.put("name", scriptName);
        map.put("locale", Locale.getDefault().getLanguage());
        map.put("title", REF_PART_TITLE_SUBCOMMANDS.get(scriptName));
        map.put("partintro", REF_PART_INTRO_SUBCOMMANDS.get(scriptName));
        List<Map<String, Object>> commands = new LinkedList<>();
        for (SubCommand subCommand : subCommands) {
            Map<String, Object> scMap = new HashMap<>();
            scMap.put("id", scriptName + "-" + subCommand.getName());
            commands.add(scMap);
        }
        map.put("subcommands", commands);
        applyTemplate(builder, "dscfgReference.ftl", map);
    }
    @Override
    public void replaceArgument(final Argument argument) {
        replaceArgumentInCollections(globalLongIDMap, globalShortIDMap, globalArgumentList, argument);
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java
New file
@@ -0,0 +1,46 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * A handler for printing sub-command usage information.
 */
//@FunctionalInterface
public interface SubCommandUsageHandler {
    /**
     * Returns properties information for the sub-command.
     *
     * @param subCommand
     *          the sub command for which to print usage information
     * @return  The properties information for the sub-command.
     */
    String getProperties(SubCommand subCommand);
    /**
     * Returns additional information for the provided sub-command argument.
     *
     * @param subCommand
     *          the sub command for which to print usage information
     * @param arg
     *          the argument for which to append additional information
     * @param nameOption
     *          the string representing the name option
     * @return  The additional information for the sub-command argument.
     */
    String getArgumentAdditionalInfo(SubCommand subCommand, Argument arg, String nameOption);
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TabSeparatedTablePrinter.java
New file
@@ -0,0 +1,137 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
/**
 * An interface for creating a tab-separated formatted table.
 * <p>
 * This table printer will replace any tab, line-feeds, or carriage return control characters encountered in a cell with
 * a single space.
 */
public final class TabSeparatedTablePrinter extends TablePrinter {
    /** Table serializer implementation. */
    private final class Serializer extends TableSerializer {
        /**
         * Counts the number of separators that should be output the next time a non-empty cell is displayed. The tab
         * separators are not displayed immediately so that we can avoid displaying unnecessary trailing separators.
         */
        private int requiredSeparators;
        /** Private constructor. */
        private Serializer() {
            // No implementation required.
        }
        @Override
        public void addCell(String s) {
            // Avoid printing tab separators for trailing empty cells.
            if (s.length() == 0) {
                requiredSeparators++;
            } else {
                for (int i = 0; i < requiredSeparators; i++) {
                    writer.print('\t');
                }
                requiredSeparators = 1;
            }
            // Replace all new-lines and tabs with a single space.
            writer.print(s.replaceAll("[\\t\\n\\r]", " "));
        }
        @Override
        public void addHeading(String s) {
            if (displayHeadings) {
                addCell(s);
            }
        }
        @Override
        public void endHeader() {
            if (displayHeadings) {
                writer.println();
            }
        }
        @Override
        public void endRow() {
            writer.println();
        }
        @Override
        public void endTable() {
            writer.flush();
        }
        @Override
        public void startHeader() {
            requiredSeparators = 0;
        }
        @Override
        public void startRow() {
            requiredSeparators = 0;
        }
    }
    /** Indicates whether or not the headings should be output. */
    private boolean displayHeadings;
    /** The output destination. */
    private PrintWriter writer;
    /**
     * Creates a new tab separated table printer for the specified output stream. Headings will not be displayed by
     * default.
     *
     * @param stream
     *            The stream to output tables to.
     */
    public TabSeparatedTablePrinter(OutputStream stream) {
        this(new BufferedWriter(new OutputStreamWriter(stream)));
    }
    /**
     * Creates a new tab separated table printer for the specified writer. Headings will not be displayed by default.
     *
     * @param writer
     *            The writer to output tables to.
     */
    public TabSeparatedTablePrinter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }
    /**
     * Specify whether or not table headings should be displayed.
     *
     * @param displayHeadings
     *            <code>true</code> if table headings should be displayed.
     */
    public void setDisplayHeadings(boolean displayHeadings) {
        this.displayHeadings = displayHeadings;
    }
    @Override
    protected TableSerializer getSerializer() {
        return new Serializer();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TableBuilder.java
New file
@@ -0,0 +1,319 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
/**
 * A class which can be used to construct tables of information to be displayed in a terminal.
 * Once built the table can be output using a {@link TableSerializer}.
 */
public final class TableBuilder {
    /**
     * The current column number in the current row where 0 represents
     * the left-most column in the table.
     */
    private int column;
    /** The current with of each column. */
    private List<Integer> columnWidths = new ArrayList<>();
    /** The list of column headings. */
    private List<LocalizableMessage> header = new ArrayList<>();
    /** The current number of rows in the table. */
    private int height;
    /** The list of table rows. */
    private List<List<String>> rows = new ArrayList<>();
    /** The linked list of sort keys comparators. */
    private List<Comparator<String>> sortComparators = new ArrayList<>();
    /** The linked list of sort keys. */
    private List<Integer> sortKeys = new ArrayList<>();
    /** The current number of columns in the table. */
    private int width;
    /**
     * Creates a new table printer.
     */
    public TableBuilder() {
        // No implementation required.
    }
    /**
     * Adds a table sort key. The table will be sorted according to the case-insensitive string ordering of the cells in
     * the specified column.
     *
     * @param column
     *            The column which will be used as a sort key.
     */
    public void addSortKey(int column) {
        addSortKey(column, String.CASE_INSENSITIVE_ORDER);
    }
    /**
     * Adds a table sort key. The table will be sorted according to the provided string comparator.
     *
     * @param column
     *            The column which will be used as a sort key.
     * @param comparator
     *            The string comparator.
     */
    public void addSortKey(int column, Comparator<String> comparator) {
        sortKeys.add(column);
        sortComparators.add(comparator);
    }
    /**
     * Appends a new blank cell to the current row.
     */
    public void appendCell() {
        appendCell("");
    }
    /**
     * Appends a new cell to the current row containing the provided boolean value.
     *
     * @param value
     *            The boolean value.
     */
    public void appendCell(boolean value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided byte value.
     *
     * @param value
     *            The byte value.
     */
    public void appendCell(byte value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided char value.
     *
     * @param value
     *            The char value.
     */
    public void appendCell(char value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided double value.
     *
     * @param value
     *            The double value.
     */
    public void appendCell(double value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided float value.
     *
     * @param value
     *            The float value.
     */
    public void appendCell(float value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided integer value.
     *
     * @param value
     *            The boolean value.
     */
    public void appendCell(int value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided long value.
     *
     * @param value
     *            The long value.
     */
    public void appendCell(long value) {
        appendCell(String.valueOf(value));
    }
    /**
     * Appends a new cell to the current row containing the provided object value.
     *
     * @param value
     *            The object value.
     */
    public void appendCell(Object value) {
        // Make sure that the first row has been created.
        if (height == 0) {
            startRow();
        }
        // Create the cell.
        String s = String.valueOf(value);
        rows.get(height - 1).add(s);
        column++;
        // Update statistics.
        if (column > width) {
            width = column;
            columnWidths.add(s.length());
        } else if (columnWidths.get(column - 1) < s.length()) {
            columnWidths.set(column - 1, s.length());
        }
    }
    /**
     * Appends a new blank column heading to the header row.
     */
    public void appendHeading() {
        appendHeading(LocalizableMessage.EMPTY);
    }
    /**
     * Appends a new column heading to the header row.
     *
     * @param value
     *            The column heading value.
     */
    public void appendHeading(LocalizableMessage value) {
        header.add(value);
        // Update statistics.
        if (header.size() > width) {
            width = header.size();
            columnWidths.add(value.length());
        } else if (columnWidths.get(header.size() - 1) < value.length()) {
            columnWidths.set(header.size() - 1, value.length());
        }
    }
    /**
     * Gets the width of the current row.
     *
     * @return Returns the width of the current row.
     */
    public int getRowWidth() {
        return column;
    }
    /**
     * Gets the number of rows in table.
     *
     * @return Returns the number of rows in table.
     */
    public int getTableHeight() {
        return height;
    }
    /**
     * Gets the number of columns in table.
     *
     * @return Returns the number of columns in table.
     */
    public int getTableWidth() {
        return width;
    }
    /**
     * Prints the table in its current state using the provided table printer.
     *
     * @param printer
     *            The table printer.
     */
    public void print(TablePrinter printer) {
        // Create a new printer instance.
        TableSerializer serializer = printer.getSerializer();
        // First sort the table.
        List<List<String>> sortedRows = new ArrayList<>(rows);
        Comparator<List<String>> comparator = new Comparator<List<String>>() {
            @Override
            public int compare(List<String> row1, List<String> row2) {
                for (int i = 0; i < sortKeys.size(); i++) {
                    String cell1 = row1.get(sortKeys.get(i));
                    String cell2 = row2.get(sortKeys.get(i));
                    int rc = sortComparators.get(i).compare(cell1, cell2);
                    if (rc != 0) {
                        return rc;
                    }
                }
                // Both rows are equal.
                return 0;
            }
        };
        Collections.sort(sortedRows, comparator);
        // Now output the table.
        serializer.startTable(height, width);
        for (int i = 0; i < width; i++) {
            serializer.addColumn(columnWidths.get(i));
        }
        // Column headings.
        serializer.startHeader();
        for (LocalizableMessage s : header) {
            serializer.addHeading(s.toString());
        }
        serializer.endHeader();
        // Table contents.
        serializer.startContent();
        for (List<String> row : sortedRows) {
            serializer.startRow();
            // Print each cell in the row, padding missing trailing cells.
            for (int i = 0; i < width; i++) {
                if (i < row.size()) {
                    serializer.addCell(row.get(i));
                } else {
                    serializer.addCell("");
                }
            }
            serializer.endRow();
        }
        serializer.endContent();
        serializer.endTable();
    }
    /**
     * Appends a new row to the table.
     */
    public void startRow() {
        rows.add(new ArrayList<String>());
        height++;
        column = 0;
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TablePrinter.java
New file
@@ -0,0 +1,40 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * An interface for incrementally configuring a table serializer. Once
 * configured, the table printer can be used to create a new
 * {@link TableSerializer} instance using the {@link #getSerializer()}
 * method.
 */
public abstract class TablePrinter {
    /**
     * Creates a new abstract table printer.
     */
    protected TablePrinter() {
        // No implementation required.
    }
    /**
     * Creates a new table serializer based on the configuration of this table printer.
     *
     * @return Returns a new table serializer based on the configuration of this table printer.
     */
    protected abstract TableSerializer getSerializer();
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TableSerializer.java
New file
@@ -0,0 +1,124 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * An interface for serializing tables.
 * <p>
 * The default implementation for each method is to do nothing.
 * Implementations must override methods as required.
 */
public abstract class TableSerializer {
    /**
     * Create a new table serializer.
     */
    protected TableSerializer() {
        // No implementation required.
    }
    /**
     * Prints a table cell.
     *
     * @param s
     *            The cell contents.
     */
    public void addCell(String s) {
        // Default implementation.
    }
    /**
     * Defines a column in the table.
     *
     * @param width
     *            The width of the column in characters.
     */
    public void addColumn(int width) {
        // Default implementation.
    }
    /**
     * Prints a column heading.
     *
     * @param s
     *            The column heading.
     */
    public void addHeading(String s) {
        // Default implementation.
    }
    /**
     * Finish printing the table contents.
     */
    public void endContent() {
        // Default implementation.
    }
    /**
     * Finish printing the column headings.
     */
    public void endHeader() {
        // Default implementation.
    }
    /**
     * Finish printing the current row of the table.
     */
    public void endRow() {
        // Default implementation.
    }
    /**
     * Finish printing the table.
     */
    public void endTable() {
        // Default implementation.
    }
    /**
     * Prepare to start printing the table contents.
     */
    public void startContent() {
        // Default implementation.
    }
    /**
     * Prepare to start printing the column headings.
     */
    public void startHeader() {
        // Default implementation.
    }
    /**
     * Prepare to start printing a new row of the table.
     */
    public void startRow() {
        // Default implementation.
    }
    /**
     * Start a new table having the specified number of rows and columns.
     *
     * @param height
     *            The number of rows in the table.
     * @param width
     *            The number of columns in the table.
     */
    public void startTable(int height, int width) {
        // Default implementation.
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/TextTablePrinter.java
New file
@@ -0,0 +1,449 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2007-2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.Utils.MAX_LINE_WIDTH;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * An interface for creating a text based table.
 * Tables have configurable column widths, padding, and column separators.
 */
public final class TextTablePrinter extends TablePrinter {
    /** Table serializer implementation. */
    private final class Serializer extends TableSerializer {
        /**The real column widths taking into account size constraints but
         not including padding or separators.*/
        private final List<Integer> columnWidths = new ArrayList<>();
        /** The cells in the current row. */
        private final List<String> currentRow = new ArrayList<>();
        /** Width of the table in columns. */
        private int totalColumns;
        /** The padding to use for indenting the table. */
        private final String indentPadding;
        /** Private constructor. */
        private Serializer() {
            // Compute the indentation padding.
            final StringBuilder builder = new StringBuilder();
            for (int i = 0; i < indentWidth; i++) {
                builder.append(' ');
            }
            this.indentPadding = builder.toString();
        }
        @Override
        public void addCell(String s) {
            currentRow.add(s);
        }
        @Override
        public void addColumn(int width) {
            columnWidths.add(width);
            totalColumns++;
        }
        @Override
        public void addHeading(String s) {
            if (displayHeadings) {
                addCell(s);
            }
        }
        @Override
        public void endHeader() {
            if (displayHeadings) {
                endRow();
                // Print the header separator.
                final StringBuilder builder = new StringBuilder(indentPadding);
                for (int i = 0; i < totalColumns; i++) {
                    int width = columnWidths.get(i);
                    if (totalColumns > 1) {
                        if (i == 0 || i == (totalColumns - 1)) {
                            // Only one lot of padding for first and last columns.
                            width += padding;
                        } else {
                            width += padding * 2;
                        }
                    }
                    for (int j = 0; j < width; j++) {
                        if (headingSeparatorStartColumn > 0) {
                            if (i < headingSeparatorStartColumn) {
                                builder.append(' ');
                            } else if (i == headingSeparatorStartColumn && j < padding) {
                                builder.append(' ');
                            } else {
                                builder.append(headingSeparator);
                            }
                        } else {
                            builder.append(headingSeparator);
                        }
                    }
                    if ((i >= headingSeparatorStartColumn) && i < (totalColumns - 1)) {
                        builder.append(columnSeparator);
                    }
                }
                writer.println(builder.toString());
            }
        }
        @Override
        public void endRow() {
            boolean isRemainingText;
            do {
                StringBuilder builder = new StringBuilder(indentPadding);
                isRemainingText = false;
                for (int i = 0; i < currentRow.size(); i++) {
                    int width = columnWidths.get(i);
                    String contents = currentRow.get(i);
                    // Determine what parts of contents can be displayed on this line.
                    String head;
                    String tail = null;
                    if (contents == null) {
                        // This cell has been displayed fully.
                        head = "";
                    } else if (contents.length() > width) {
                        // We're going to have to split the cell on next word boundary.
                        int endIndex = contents.lastIndexOf(' ', width);
                        if (endIndex == -1) {
                            endIndex = width;
                            head = contents.substring(0, endIndex);
                            tail = contents.substring(endIndex);
                        } else {
                            head = contents.substring(0, endIndex);
                            tail = contents.substring(endIndex + 1);
                        }
                    } else {
                        // The contents fits ok.
                        head = contents;
                    }
                    // Add this cell's contents to the current line.
                    if (i > 0) {
                        // Add right padding for previous cell.
                        for (int j = 0; j < padding; j++) {
                            builder.append(' ');
                        }
                        // Add separator.
                        builder.append(columnSeparator);
                        // Add left padding for this cell.
                        for (int j = 0; j < padding; j++) {
                            builder.append(' ');
                        }
                    }
                    // Add cell contents.
                    builder.append(head);
                    // Now pad with extra space to make up the width.
                    // Only if it's not the last cell (see issue #3210)
                    if (i != currentRow.size() - 1) {
                        for (int j = head.length(); j < width; j++) {
                            builder.append(' ');
                        }
                    }
                    // Update the row contents.
                    currentRow.set(i, tail);
                    if (tail != null) {
                        isRemainingText = true;
                    }
                }
                // Output the line.
                writer.println(builder.toString());
            } while (isRemainingText);
        }
        @Override
        public void endTable() {
            writer.flush();
        }
        @Override
        public void startHeader() {
            determineColumnWidths();
            currentRow.clear();
        }
        @Override
        public void startRow() {
            currentRow.clear();
        }
        /** We need to calculate the effective width of each column. */
        private void determineColumnWidths() {
            // First calculate the minimum width so that we know how much
            // expandable columns can expand.
            int minWidth = indentWidth;
            int expandableColumnSize = 0;
            for (int i = 0; i < totalColumns; i++) {
                int actualSize = columnWidths.get(i);
                if (fixedColumns.containsKey(i)) {
                    int requestedSize = fixedColumns.get(i);
                    if (requestedSize == 0) {
                        expandableColumnSize += actualSize;
                    } else {
                        columnWidths.set(i, requestedSize);
                        minWidth += requestedSize;
                    }
                } else {
                    minWidth += actualSize;
                }
                // Must also include padding and separators.
                if (i > 0) {
                    minWidth += padding * 2 + columnSeparator.length();
                }
            }
            if (minWidth > totalWidth) {
                // The table is too big: leave expandable columns at their
                // requested width, as there's not much else that can be done.
            } else {
                int available = totalWidth - minWidth;
                if (expandableColumnSize > available) {
                    // Only modify column sizes if necessary.
                    for (int i = 0; i < totalColumns; i++) {
                        int actualSize = columnWidths.get(i);
                        if (fixedColumns.containsKey(i)) {
                            int requestedSize = fixedColumns.get(i);
                            if (requestedSize == 0) {
                                // Calculate size based on requested actual size as a
                                // proportion of the total.
                                requestedSize = (actualSize * available) / expandableColumnSize;
                                columnWidths.set(i, requestedSize);
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * The default string which should be used to separate one column from the next (not including padding).
     */
    private static final String DEFAULT_COLUMN_SEPARATOR = "";
    /**
     * The default character which should be used to separate the table heading row from the rows beneath.
     */
    private static final char DEFAULT_HEADING_SEPARATOR = '-';
    /**
     * The default padding which will be used to separate a cell's contents from its adjacent column separators.
     */
    private static final int DEFAULT_PADDING = 1;
    /**
     * The string which should be used to separate one column
     * from the next (not including padding).
     */
    private String columnSeparator = DEFAULT_COLUMN_SEPARATOR;
    /** Indicates whether or not the headings should be output. */
    private boolean displayHeadings = true;
    /** Table indicating whether or not a column is fixed width. */
    private final Map<Integer, Integer> fixedColumns = new HashMap<>();
    /** The number of characters the table should be indented. */
    private int indentWidth;
    /** The character which should be used to separate the table heading row from the rows beneath. */
    private char headingSeparator = DEFAULT_HEADING_SEPARATOR;
    /** The column where the heading separator should begin. */
    private int headingSeparatorStartColumn;
    /**
     * The padding which will be used to separate a cell's
     * contents from its adjacent column separators.
     */
    private int padding = DEFAULT_PADDING;
    /** Total permitted width for the table which expandable columns can use up. */
    private int totalWidth = MAX_LINE_WIDTH;
    /** The output destination. */
    private PrintWriter writer;
    /**
     * Creates a new text table printer for the specified output stream. The text table printer will have the following
     * initial settings:
     * <ul>
     * <li>headings will be displayed
     * <li>no separators between columns
     * <li>columns are padded by one character
     * </ul>
     *
     * @param stream
     *            The stream to output tables to.
     */
    public TextTablePrinter(OutputStream stream) {
        this(new BufferedWriter(new OutputStreamWriter(stream)));
    }
    /**
     * Creates a new text table printer for the specified writer. The text table printer will have the following initial
     * settings:
     * <ul>
     * <li>headings will be displayed
     * <li>no separators between columns
     * <li>columns are padded by one character
     * </ul>
     *
     * @param writer
     *            The writer to output tables to.
     */
    public TextTablePrinter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }
    /**
     * Sets the column separator which should be used to separate one column from the next (not including padding).
     *
     * @param columnSeparator
     *            The column separator.
     */
    public void setColumnSeparator(String columnSeparator) {
        this.columnSeparator = columnSeparator;
    }
    /**
     * Set the maximum width for a column. If a cell is too big to fit in its column then it will be wrapped.
     *
     * @param column
     *            The column to make fixed width (0 is the first column).
     * @param width
     *            The width of the column (this should not include column separators or padding), or <code>0</code> to
     *            indicate that this column should be expandable.
     * @throws IllegalArgumentException
     *             If column is less than 0.
     */
    public void setColumnWidth(int column, int width) {
        if (column < 0) {
            throw new IllegalArgumentException("Negative column " + column);
        }
        if (width < 0) {
            throw new IllegalArgumentException("Negative width " + width);
        }
        fixedColumns.put(column, width);
    }
    /**
     * Specify whether the column headings should be displayed or not.
     *
     * @param displayHeadings
     *            <code>true</code> if column headings should be displayed.
     */
    public void setDisplayHeadings(boolean displayHeadings) {
        this.displayHeadings = displayHeadings;
    }
    /**
     * Sets the heading separator which should be used to separate the table heading row from the rows beneath.
     *
     * @param headingSeparator
     *            The heading separator.
     */
    public void setHeadingSeparator(char headingSeparator) {
        this.headingSeparator = headingSeparator;
    }
    /**
     * Sets the heading separator start column. The heading separator will only be display in the specified column and
     * all subsequent columns. Usually this should be left at zero (the default) but sometimes it useful to indent the
     * heading separate in order to provide additional emphasis (for example in menus).
     *
     * @param startColumn
     *            The heading separator start column.
     */
    public void setHeadingSeparatorStartColumn(int startColumn) {
        if (startColumn < 0) {
            throw new IllegalArgumentException("Negative start column " + startColumn);
        }
        this.headingSeparatorStartColumn = startColumn;
    }
    /**
     * Sets the amount of characters that the table should be indented. By default the table is not indented.
     *
     * @param indentWidth
     *            The number of characters the table should be indented.
     * @throws IllegalArgumentException
     *             If indentWidth is less than 0.
     */
    public void setIndentWidth(int indentWidth) {
        if (indentWidth < 0) {
            throw new IllegalArgumentException("Negative indentation width " + indentWidth);
        }
        this.indentWidth = indentWidth;
    }
    /**
     * Sets the padding which will be used to separate a cell's contents from its adjacent column separators.
     *
     * @param padding
     *            The padding.
     */
    public void setPadding(int padding) {
        this.padding = padding;
    }
    /**
     * Sets the total permitted width for the table which expandable columns can use up.
     *
     * @param totalWidth
     *            The total width.
     */
    public void setTotalWidth(int totalWidth) {
        this.totalWidth = totalWidth;
    }
    @Override
    protected TableSerializer getSerializer() {
        return new Serializer();
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java
New file
@@ -0,0 +1,80 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import org.forgerock.i18n.LocalizableMessage;
/**
 * An interface for an object that holds reference documentation for a command-line tool.
 */
public interface ToolRefDocContainer {
    /**
     * Gets a short description for this tool, suitable in a man page summary line.
     *
     * @return  A short description for this tool,
     *          suitable in a man page summary line,
     *          or LocalizableMessage.EMPTY if there is no short description.
     */
    LocalizableMessage getShortToolDescription();
    /**
     * Sets a short description for this tool, suitable in a man page summary line.
     *
     * @param   shortDescription    The short description for this tool,
     *                              suitable in a man page summary line.
     */
    void setShortToolDescription(final LocalizableMessage shortDescription);
    /**
     * Retrieves a supplement to the description for this tool,
     * intended for use in generated reference documentation.
     *
     * @return A supplement to the description for this tool
     *         intended for use in generated reference documentation,
     *         or LocalizableMessage.EMPTY if there is no supplement.
     */
    LocalizableMessage getDocToolDescriptionSupplement();
    /**
     * Sets a supplement to the description for this tool,
     * intended for use in generated reference documentation.
     *
     * @param docToolDescriptionSupplement  The supplement to the description for this tool
     *                                      intended for use in generated reference documentation.
     */
    void setDocToolDescriptionSupplement(final LocalizableMessage docToolDescriptionSupplement);
    /**
     * Retrieves a supplement to the description for all subcommands of this tool,
     * intended for use in generated reference documentation.
     *
     * @return A supplement to the description for all subcommands of this tool
     *         intended for use in generated reference documentation,
     *         or LocalizableMessage.EMPTY if there is no supplement.
     */
    LocalizableMessage getDocSubcommandsDescriptionSupplement();
    /**
     * Sets a supplement to the description for all subcommands of this tool,
     * intended for use in generated reference documentation.
     *
     * @param docSubcommandsDescriptionSupplement
     *          The supplement to the description for all subcommands of this tool
     *          intended for use in generated reference documentation.
     */
    void setDocSubcommandsDescriptionSupplement(final LocalizableMessage docSubcommandsDescriptionSupplement);
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolVersionHandler.java
New file
@@ -0,0 +1,83 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2015-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
/** Class that prints the version of the SDK to System.out. */
public final class ToolVersionHandler implements VersionHandler {
    /**
     * Returns a {@link VersionHandler} which should be used by OpenDJ SDK tools.
     * <p>
     * The printed version and SCM revision will be the one of the opendj-core module.
     * @return A {@link VersionHandler} which should be used by OpenDJ SDK tools.
     */
    public static VersionHandler newSdkVersionHandler() {
        return newToolVersionHandler("opendj-core");
    }
    /**
     * Returns a {@link VersionHandler} which should be used to print version and SCM revision of a module.
     * <p>
     * The printed version and SCM revision will be read from the module MANIFEST.MF‌ file.
     * @param moduleName
     *       Name of the module which uniquely identify the URL of the MANIFEST‌.MF file.
     * @return A {@link VersionHandler} which should be used by OpenDJ SDK tools.
     */
    public static VersionHandler newToolVersionHandler(final String moduleName) {
        return new ToolVersionHandler(moduleName);
    }
    private final String moduleName;
    private ToolVersionHandler(final String moduleName) {
        this.moduleName = moduleName;
    }
    @Override
    public void printVersion() {
        System.out.println(getVersion());
    }
    @Override
    public String toString() {
        return getClass().getSimpleName() + "(" + getVersion() + ")";
    }
    private String getVersion() {
        try {
            final Enumeration<URL> manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
            while (manifests.hasMoreElements()) {
                final URL manifestUrl = manifests.nextElement();
                if (manifestUrl.toString().contains(moduleName)) {
                    try (InputStream manifestStream = manifestUrl.openStream()) {
                        final Attributes attrs = new Manifest(manifestStream).getMainAttributes();
                        return attrs.getValue("Bundle-Version") + " (revision " + attrs.getValue("SCM-Revision") + ")";
                    }
                }
            }
            return null;
        } catch (IOException e) {
            throw new RuntimeException("IOException while determining opendj tool version", e);
        }
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/Utils.java
New file
@@ -0,0 +1,740 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2010 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import static com.forgerock.opendj.cli.CliMessages.*;
import com.forgerock.opendj.util.OperatingSystem;
import static com.forgerock.opendj.util.StaticUtils.EOL;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.TimeZone;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.NamingException;
import javax.naming.NamingSecurityException;
import javax.naming.NoPermissionException;
import javax.net.ssl.SSLHandshakeException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.LocalizableMessageDescriptor;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.RDN;
/** This class provides utility functions for all the client side tools. */
public final class Utils {
    /** Platform appropriate line separator. */
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
    /**
     * The value used to display arguments that must be obfuscated (such as passwords). This does not require
     * localization (since the output of command builder by its nature is not localized).
     */
    public static final String OBFUSCATED_VALUE = "******";
    /** The maximum number of times we try to confirm. */
    public static final int CONFIRMATION_MAX_TRIES = 5;
    /**
     * The date format string that will be used to construct and parse dates represented using generalized time. It is
     * assumed that the provided date formatter will be set to UTC.
     */
    public static final String DATE_FORMAT_LOCAL_TIME = "dd/MMM/yyyy:HH:mm:ss Z";
    /**
     * Returns the message to be displayed in the file with the equivalent command-line with information about the
     * current time.
     *
     * @return the message to be displayed in the file with the equivalent command-line with information about the
     *         current time.
     */
    public static String getCurrentOperationDateMessage() {
        String date = formatDateTimeStringForEquivalentCommand(new Date());
        return INFO_OPERATION_START_TIME_MESSAGE.get(date).toString();
    }
    private static final String COMMENT_SHELL_UNIX = "# ";
    private static final String COMMENT_BATCH_WINDOWS = "rem ";
    /** The String used to write comments in a shell (or batch) script. */
    public static final String SHELL_COMMENT_SEPARATOR = OperatingSystem.isWindows() ? COMMENT_BATCH_WINDOWS
            : COMMENT_SHELL_UNIX;
    /** The column at which to wrap long lines of output in the command-line tools. */
    public 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;
    }
    /**
     * Formats a Date to String representation in "dd/MMM/yyyy:HH:mm:ss Z".
     *
     * @param date
     *            The date to format; null if <code>date</code> is null.
     * @return A string representation of the date.
     */
    public static String formatDateTimeStringForEquivalentCommand(final Date date) {
        if (date != null) {
            final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_LOCAL_TIME);
            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            return dateFormat.format(date);
        }
        return null;
    }
    /**
     * 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.
     */
    public static int filterExitCode(final int exitCode) {
        if (exitCode < 0) {
            return 255;
        } else if (exitCode > 255) {
            return 255;
        } else {
            return exitCode;
        }
    }
    /**
     * 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.
     */
    public static byte[] readBytesFromFile(final String filePath) throws IOException {
        final File file = new File(filePath);
        final long length = file.length();
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] 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;
        }
    }
    /**
     * 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public static String wrapText(final String text, int width, final int indent) {
        if (text == null) {
            return "";
        }
        // 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();
        final StringTokenizer lineTokenizer = new StringTokenizer(text, "\r\n", true);
        while (lineTokenizer.hasMoreTokens()) {
            final String line = lineTokenizer.nextToken();
            if ("\r".equals(line) || "\n".equals(line)) {
                // 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 (" ".equals(word)) {
                        // 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).append(lineBuffer).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 current 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).append(lineBuffer).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();
    }
    /**
     * Checks the java version.
     *
     * @throws ClientException
     *             If the java version we are running on is not compatible.
     */
    public static void checkJavaVersion() throws ClientException {
        final String version = System.getProperty("java.specification.version");
        if (Float.valueOf(version) < CliConstants.MINIMUM_JAVA_VERSION) {
            final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
            throw new ClientException(ReturnCode.JAVA_VERSION_INCOMPATIBLE,
                    ERR_INCOMPATIBLE_JAVA_VERSION.get(CliConstants.MINIMUM_JAVA_VERSION, version, javaBin), null);
        }
    }
    /**
     * Returns the default host name.
     *
     * @return The default host name or empty string if the host name cannot be resolved.
     */
    public static String getDefaultHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            // Fails.
        }
        String host = System.getenv("COMPUTERNAME"); // Windows.
        if (host != null) {
            return host;
        }
        host = System.getenv("HOSTNAME"); // Unix.
        if (host != null) {
            return host;
        }
        return "";
    }
    /**
     * Tells whether the provided Throwable was caused because of a problem with a certificate while trying to establish
     * a connection.
     *
     * @param t
     *            The Throwable to analyze.
     * @return <CODE>true</CODE> if the provided Throwable was caused because of a problem with a certificate while
     *         trying to establish a connection and <CODE>false</CODE> otherwise.
     */
    public static boolean isCertificateException(Throwable t) {
        while (t != null) {
            if (t instanceof SSLHandshakeException || t instanceof GeneralSecurityException) {
                return true;
            }
            t = t.getCause();
        }
        return false;
    }
    /**
     * Returns a message object for the given NamingException.
     *
     * @param ne
     *            The NamingException.
     * @param hostPort
     *            The hostPort representation of the server we were contacting when the NamingException occurred.
     * @return A message object for the given NamingException.
     */
    public static LocalizableMessage getMessageForException(NamingException ne, String hostPort) {
        String arg;
        if (ne.getLocalizedMessage() != null) {
            arg = ne.getLocalizedMessage();
        } else if (ne.getExplanation() != null) {
            arg = ne.getExplanation();
        } else {
            arg = ne.toString(true);
        }
        if (Utils.isCertificateException(ne)) {
            return INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get(hostPort, arg);
        } else if (ne instanceof AuthenticationException) {
            return INFO_CANNOT_CONNECT_TO_REMOTE_AUTHENTICATION.get(hostPort, arg);
        } else if (ne instanceof NoPermissionException) {
            return INFO_CANNOT_CONNECT_TO_REMOTE_PERMISSIONS.get(hostPort, arg);
        } else if (ne instanceof NamingSecurityException) {
            return INFO_CANNOT_CONNECT_TO_REMOTE_PERMISSIONS.get(hostPort, arg);
        } else if (ne instanceof CommunicationException) {
            return ERR_CANNOT_CONNECT_TO_REMOTE_COMMUNICATION.get(hostPort, arg);
        } else {
            return INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get(hostPort, arg);
        }
    }
    /**
     * Returns a localized message for a given properties key an throwable.
     *
     * @param message
     *            prefix
     * @param t
     *            the throwable for which we want to get a message.
     * @return a localized message for a given properties key and throwable.
     */
    public static LocalizableMessage getThrowableMsg(final LocalizableMessage message, final Throwable t) {
        LocalizableMessageDescriptor.Arg1<Object> tag;
        if (isOutOfMemory(t)) {
            tag = INFO_EXCEPTION_OUT_OF_MEMORY_DETAILS;
        } else {
            tag = INFO_EXCEPTION_DETAILS;
        }
        final LocalizableMessageBuilder mb = new LocalizableMessageBuilder(message);
        String detail = t.toString();
        if (detail != null) {
            mb.append("  ").append(tag.get(detail));
        }
        return mb.toMessage();
    }
    /**
     * Returns <CODE>true</CODE> if we can write on the provided path and <CODE>false</CODE> otherwise.
     *
     * @param path
     *            the path.
     * @return <CODE>true</CODE> if we can write on the provided path and <CODE>false</CODE> otherwise.
     */
    public static boolean canWrite(String path) {
        final File file = new File(path);
        if (file.exists()) {
            return file.canWrite();
        }
        final File parentFile = file.getParentFile();
        return parentFile != null && parentFile.canWrite();
    }
    /** Prevent instantiation. */
    private Utils() {
        // Do nothing.
    }
    /**
     * Returns {@code true} if the the provided string is a DN and {@code false} otherwise.
     *
     * @param dn
     *            The String we are analyzing.
     * @return {@code true} if the the provided string is a DN and {@code false} otherwise.
     */
    public static boolean isDN(String dn) {
        try {
            DN.valueOf(dn);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }
    /**
     * Returns the DN of the global administrator for a given UID.
     *
     * @param uid
     *            The UID to be used to generate the DN.
     * @return The DN of the administrator for the given UID.
     */
    public static String getAdministratorDN(String uid) {
        return RDN.valueOf("cn=" + uid) + ",cn=Administrators, cn=admin data";
    }
    /**
     * Tells whether this throwable has been generated for an out of memory error or not.
     *
     * @param t
     *            The throwable to analyze.
     * @return {@code true} if the throwable was generated by an out of memory error and false otherwise.
     */
    private static boolean isOutOfMemory(Throwable t) {
        boolean isOutOfMemory = false;
        while (!isOutOfMemory && t != null) {
            if (t instanceof OutOfMemoryError) {
                isOutOfMemory = true;
            } else if (t instanceof IOException) {
                final String msg = t.toString();
                if (msg != null) {
                    isOutOfMemory = msg.contains("Not enough space");
                }
            }
            t = t.getCause();
        }
        return isOutOfMemory;
    }
    /**
     * Returns the string that can be used to represent a given host name in a LDAP URL.
     * This method must be used when we have IPv6 addresses (the address in the LDAP URL
     *  must be enclosed with brackets).
     *  E.g:<pre>
     *  -h "[2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]"
     *  </pre>
     *
     * @param host
     *            The host name.
     * @return The String that can be used to represent a given host name in a LDAP URL.
     */
    public static String getHostNameForLdapUrl(String host) {
        if (host != null && host.contains(":")) {
            // Assume an IPv6 address has been specified and adds the brackets
            // for the URL.
            host = host.trim();
            if (!host.startsWith("[")) {
                host = "[" + host;
            }
            if (!host.endsWith("]")) {
                host = host + "]";
            }
        }
        return host;
    }
    /**
     * Prints the provided string on the provided stream.
     *
     * @param stream
     *            The stream to print the message.
     * @param message
     *            The message to print.
     */
    public static void printWrappedText(final PrintStream stream, final String message) {
        if (stream != null && message != null && !message.isEmpty()) {
            stream.println(wrapText(message, MAX_LINE_WIDTH));
        }
    }
    /**
     * Print the provided message on the provided stream.
     *
     * @param stream
     *            The stream to print the message.
     * @param message
     *            The message to print.
     */
    public static void printWrappedText(final PrintStream stream, final LocalizableMessage message) {
        printWrappedText(stream, message != null ? message.toString() : null);
    }
    /**
     * Repeats the given {@link char} n times.
     *
     * @param charToRepeat
     *      The {@link char} to repeat.
     * @param length
     *      The repetition count.
     * @return The given {@link char} n times.
     */
    public static String repeat(final char charToRepeat, final int length) {
        final char[] str = new char[length];
        Arrays.fill(str, charToRepeat);
        return new String(str);
    }
    /**
     * Return a {@link ValidationCallback<Integer>} which can be used to validate a port number.
     *
     * @param defaultPort
     *        The default value to suggest to the user.
     * @return a {@link ValidationCallback<Integer>} which can be used to validate a port number.
     */
    public static ValidationCallback<Integer> portValidationCallback(final int defaultPort) {
        return new ValidationCallback<Integer>() {
            @Override
            public Integer validate(ConsoleApplication app, String rawInput) throws ClientException {
                final String input = rawInput.trim();
                if (input.length() == 0) {
                    return defaultPort;
                }
                try {
                    int i = Integer.parseInt(input);
                    if (i < 1 || i > 65535) {
                        throw new NumberFormatException();
                    }
                    return i;
                } catch (NumberFormatException e) {
                    // Try again...
                    app.println();
                    app.println(ERR_BAD_PORT_NUMBER.get(input));
                    app.println();
                    return null;
                }
            }
        };
    }
    /**
     * Throws an {@link ArgumentException} if both provided {@link Argument} are presents in the command line arguments.
     *
     * @param arg1
     *         The first {@link Argument} which should not be present if {@literal arg2} is.
     * @param arg2
     *         The second {@link Argument} which should not be present if {@literal arg1} is.
     * @throws ArgumentException
     *         If both provided {@link Argument} are presents in the command line arguments
     */
    public static void throwIfArgumentsConflict(final Argument arg1, final Argument arg2) throws ArgumentException {
        if (argsConflicts(arg1, arg2)) {
            throw new ArgumentException(conflictingArgsErrorMessage(arg1, arg2));
        }
    }
    /**
     * Adds a {@link LocalizableMessage} to the provided {@link Collection<LocalizableMessage>}
     * if both provided {@link Argument} are presents in the command line arguments.
     *
     * @param errors
     *         The {@link Collection<LocalizableMessage>} to use to add the conflict error (if occurs).
     * @param arg1
     *         The first {@link Argument} which should not be present if {@literal arg2} is.
     * @param arg2
     *         The second {@link Argument} which should not be present if {@literal arg1} is.
     */
    public static void addErrorMessageIfArgumentsConflict(
            final Collection<LocalizableMessage> errors, final Argument arg1, final Argument arg2) {
        if (argsConflicts(arg1, arg2)) {
            errors.add(conflictingArgsErrorMessage(arg1, arg2));
        }
    }
    /**
     * Return {@code true} if provided {@link Argument} are presents in the command line arguments.
     * <p>
     * If so, adds a {@link LocalizableMessage} to the provided {@link LocalizableMessageBuilder}.
     *
     * @param builder
     *         The {@link LocalizableMessageBuilder} to use to write the conflict error (if occurs).
     * @param arg1
     *         The first {@link Argument} which should not be present if {@literal arg2} is.
     * @param arg2
     *         The second {@link Argument} which should not be present if {@literal arg1} is.
     * @return {@code true} if provided {@link Argument} are presents in the command line arguments.
     */
    public static boolean appendErrorMessageIfArgumentsConflict(
        final LocalizableMessageBuilder builder, final Argument arg1, final Argument arg2) {
        if (argsConflicts(arg1, arg2)) {
            if (builder.length() > 0) {
                builder.append(LINE_SEPARATOR);
            }
            builder.append(conflictingArgsErrorMessage(arg1, arg2));
            return true;
        }
        return false;
    }
    private static boolean argsConflicts(final Argument arg1, final Argument arg2) {
        return arg1.isPresent() && arg2.isPresent();
    }
    /**
     * Returns a {@link LocalizableMessage} which explains to the user
     * that provided {@link Argument}s can not be used together on the command line.
     *
     * @param arg1
     *         The first {@link Argument} which conflicts with {@literal arg2}.
     * @param arg2
     *         The second {@link Argument} which conflicts with {@literal arg1}.
     * @return A {@link LocalizableMessage} which explains to the user that arguments
     *         can not be used together on the command line.
     */
    public static LocalizableMessage conflictingArgsErrorMessage(final Argument arg1, final Argument arg2) {
        return ERR_TOOL_CONFLICTING_ARGS.get(arg1.getLongIdentifier(), arg2.getLongIdentifier());
    }
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/ValidationCallback.java
New file
@@ -0,0 +1,43 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * An interface for validating user input.
 *
 * @param <T>
 *            The type of the decoded input.
 */
public interface ValidationCallback<T> {
    /**
     * Validates and decodes the user-provided input. Implementations must validate
     * <code>input</code> and return the decoded value if the input is acceptable.
     * If the input is unacceptable, implementations must return
     * <code>null</code> and output a user friendly error message to the provided
     * application console.
     *
     * @param app
     *            The console application.
     * @param input
     *            The user input to be validated.
     * @return Returns the decoded input if the input is valid, or <code>null</code> if it is not.
     * @throws ClientException
     *             If an unexpected error occurred which prevented validation.
     */
    T validate(ConsoleApplication app, String input) throws ClientException;
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/VersionHandler.java
New file
@@ -0,0 +1,27 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
/**
 * A handler for printing product version.
 */
//@FunctionalInterface
public interface VersionHandler {
    /** Invoked when the version of the product should be printed. */
    void printVersion();
}
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/package-info.java
New file
@@ -0,0 +1,19 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014 ForgeRock AS.
 */
/**
 * Classes implementing the OpenDJ CLI shared APIs.
 */
package com.forgerock.opendj.cli;
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli.properties
New file
@@ -0,0 +1,463 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
# Copyright 2014-2016 ForgeRock AS.
ERR_ARG_NO_VALUE_PLACEHOLDER=The %s argument is configured to take \
 a value but no value placeholder has been defined for it
ERR_ARG_NO_INT_VALUE=The %s argument does not have any value that \
 may be retrieved as an integer
ERR_ARG_CANNOT_DECODE_AS_INT=The provided value "%s" for the %s \
 argument cannot be decoded as an integer
ERR_ARG_INT_MULTIPLE_VALUES=The %s argument has multiple values and \
 therefore cannot be decoded as a single integer value
ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND=The %s argument \
 configuration is invalid because the lower bound of %d is greater than the \
 upper bound of %d
ERR_INTARG_VALUE_BELOW_LOWER_BOUND=The provided %s value %d is \
 unacceptable because it is below the lower bound of %d
ERR_INTARG_VALUE_ABOVE_UPPER_BOUND=The provided %s value %d is \
 unacceptable because it is above the upper bound of %d
ERR_BOOLEANARG_NO_VALUE_ALLOWED=The provided %s value is \
 unacceptable because Boolean arguments are never allowed to have values
ERR_MCARG_VALUE_NOT_ALLOWED=The provided %s value %s is \
 unacceptable because it is not included in the set of allowed values for that \
 argument
ERR_FILEARG_NO_SUCH_FILE=The file %s specified for argument %s does \
 not exist
ERR_FILEARG_CANNOT_VERIFY_FILE_EXISTENCE=An error occurred while \
 trying to verify the existence of file %s specified for argument %s:  %s
ERR_FILEARG_CANNOT_OPEN_FILE=An error occurred while trying to open \
 file %s specified for argument %s for reading:  %s
ERR_FILEARG_CANNOT_READ_FILE=An error occurred while trying to read \
 from file %s specified for argument %s:  %s
ERR_FILEARG_EMPTY_FILE=The file %s specified for argument %s exists \
 but is empty
ERR_ARGPARSER_DUPLICATE_SHORT_ID=Cannot add argument %s to the \
 argument list because its short identifier -%s conflicts with the %s argument \
 that has already been defined
ERR_ARGPARSER_DUPLICATE_LONG_ID=Cannot add argument %s to the \
 argument list because there is already one defined with the same identifier
ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE=An error occurred while \
 attempting to read the contents of the argument properties file %s:  %s
ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS=The provided set of \
 command-line arguments contained too many unnamed trailing arguments.  The \
 maximum number of allowed trailing arguments is %d
ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME=The provided argument "%s" is \
 invalid because it does not include the argument name
ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID=Argument --%s is not allowed \
 for use with this program
ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID=Argument --%s \
 requires a value but none was provided
ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID=The provided value \
 "%s" for argument --%s is not acceptable:  %s
ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID=The argument --%s was \
 included multiple times in the provided set of arguments but it does not \
 allow multiple values
ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE=A value was \
 provided for argument --%s but that argument does not take a value
ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT=The dash character by itself \
 is invalid for use as an argument name
ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID=Argument -%s is not allowed \
 for use with this program
ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID=Argument -%s \
 requires a value but none was provided
ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID=The provided value \
 "%s" for argument -%s is not acceptable:  %s
ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID=The argument -%s was \
 included multiple times in the provided set of arguments but it does not \
 allow multiple values
ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES=The provided argument block \
 '-%s%s' is illegal because the '%s' argument requires a value but is in the \
 same block as at least one other argument that does not require a value
ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT=Argument "%s" does not \
 start with one or two dashes and unnamed trailing arguments are not allowed
ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS=At least %d unnamed \
 trailing arguments are required in the argument list, but too few were \
 provided
ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG=The argument %s is required \
 to have a value but none was provided in the argument list and no default \
 value is available
INFO_TIME_IN_SECONDS=%d seconds
INFO_TIME_IN_MINUTES_SECONDS=%d minutes, %d seconds
INFO_TIME_IN_HOURS_MINUTES_SECONDS=%d hours, %d minutes, %d seconds
INFO_TIME_IN_DAYS_HOURS_MINUTES_SECONDS=%d days, %d hours, %d minutes, %d \
 seconds
INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE=Command options:
INFO_MENU_PROMPT_RETURN_TO_CONTINUE=Press RETURN to continue
ERR_CONSOLE_INPUT_ERROR=The response could not be read from the console due to the following error: %s
INFO_PROMPT_SINGLE_DEFAULT=%s [%s]:
INFO_ARGPARSER_USAGE_JAVA_CLASSNAME=Usage:  java %s  {options}
INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME=Usage:  %s  {options}
INFO_ARGPARSER_USAGE_TRAILINGARGS={trailing-arguments}
INFO_ARGPARSER_USAGE_DEFAULT_VALUE=Default value: %s
INFO_SUBCMDPARSER_OPTIONS={options}
INFO_GLOBAL_OPTIONS=Global Options:
INFO_GLOBAL_OPTIONS_REFERENCE=See "%s --help"
INFO_GLOBAL_HELP_REFERENCE=See "%s --help" to get more usage help
INFO_SUBCMD_OPTIONS=SubCommand Options:
INFO_ARGPARSER_USAGE=Usage:
INFO_SUBCMDPARSER_SUBCMD_AND_OPTIONS={subcommand} {options}
INFO_SUBCMDPARSER_SUBCMD_HELP_HEADING=To get the list of subcommands use:
INFO_SUBCMDPARSER_SUBCMD_HEADING=Available subcommands:
ERR_ARG_SUBCOMMAND_INVALID=Invalid subcommand
INFO_SUBCMDPARSER_GLOBAL_HEADING=The global options are:
#
# Extension messages
#
#
# Tools messages
#
INFO_DESCRIPTION_TRUSTALL=Trust all server SSL certificates
INFO_DESCRIPTION_BINDDN=DN to use to bind to the server
INFO_DESCRIPTION_BINDPASSWORD=Password to use to bind to \
 the server. Use -w - to ensure that the command prompts for the password, \
 rather than entering the password as a command argument
INFO_DESCRIPTION_BINDPASSWORDFILE=Bind password file
INFO_DESCRIPTION_ENCODING=Use the specified character set for \
 command-line input
INFO_DESCRIPTION_VERBOSE=Use verbose mode
INFO_DESCRIPTION_KEYSTOREPATH=Certificate key store path
INFO_DESCRIPTION_TRUSTSTOREPATH=Certificate trust store path
INFO_DESCRIPTION_HOST=Directory server hostname or IP address
INFO_DESCRIPTION_PORT=Directory server port number
INFO_DESCRIPTION_SHOWUSAGE=Display this usage information
INFO_DESCRIPTION_CONTROLS=Use a request control with the provided \
 information
INFO_DESCRIPTION_CONTINUE_ON_ERROR=Continue processing even if there are \
 errors
INFO_DESCRIPTION_USE_SSL=Use SSL for secure communication with the server
INFO_DESCRIPTION_START_TLS=Use StartTLS to secure communication with the \
 server
INFO_DESCRIPTION_PROXYAUTHZID=Use the proxied authorization \
 control with the given authorization ID
INFO_DESCRIPTION_RESTART=Attempt to automatically restart the \
 server once it has stopped
INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE=Search scope ('base', 'one', 'sub', \
 or 'subordinate')
ERR_LDAPAUTH_UNSUPPORTED_SASL_MECHANISM=The requested SASL mechanism \
 "%s" is not supported by this client
ERR_LDAPAUTH_SASL_AUTHID_REQUIRED=The "authid" SASL property is \
 required for use with the %s mechanism
INFO_DESCRIPTION_VERSION=LDAP protocol version number
INFO_DESCRIPTION_NOOP=Show what would be done but do not perform any \
 operation
INFO_DESCRIPTION_REPORT_AUTHZID=Use the authorization identity control
INFO_DESCRIPTION_USE_PWP_CONTROL=Use the password policy request control
ERR_TOOL_CONFLICTING_ARGS=You may not provide both the --%s and \
 the --%s arguments
ERR_TOOL_SASLEXTERNAL_NEEDS_SSL_OR_TLS=SASL EXTERNAL \
 authentication may only be requested if SSL or StartTLS is used
ERR_TOOL_SASLEXTERNAL_NEEDS_KEYSTORE=SASL EXTERNAL authentication \
 may only be used if a client certificate key store is specified
INFO_DESCRIPTION_TRUSTSTOREPASSWORD=Certificate trust store PIN
INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE=Certificate trust store PIN file
INFO_DESCRIPTION_PRODUCT_VERSION=Display Directory Server version \
 information
INFO_DESCRIPTION_SCRIPT_FRIENDLY=Use script-friendly mode
ERR_LDAP_CONN_CANNOT_INITIALIZE_SSL=ERROR:  Unable to perform SSL \
 initialization:  %s
ERR_LDAP_CONN_CANNOT_PARSE_SASL_OPTION=ERROR:  The provided SASL \
 option string "%s" could not be parsed in the form "name=value"
INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS=SASL bind options
INFO_DESCRIPTION_PROP_FILE_PATH=Path to the file containing default \
  property values used for command line arguments
INFO_DESCRIPTION_NO_PROP_FILE=No properties file will be \
  used to get default command line argument values
INFO_DESCRIPTION_GENERAL_ARGS=General options:
INFO_DESCRIPTION_IO_ARGS=Utility input/output options:
INFO_DESCRIPTION_LDAP_CONNECTION_ARGS=LDAP connection options:
INFO_FILE_PLACEHOLDER={file}
INFO_KEYSTOREPATH_PLACEHOLDER={keyStorePath}
INFO_TRUSTSTOREPATH_PLACEHOLDER={trustStorePath}
INFO_BINDPWD_FILE_PLACEHOLDER={bindPasswordFile}
INFO_HOST_PLACEHOLDER={host}
INFO_PORT_PLACEHOLDER={port}
INFO_BASEDN_PLACEHOLDER={baseDN}
INFO_BINDDN_PLACEHOLDER={bindDN}
INFO_BINDPWD_PLACEHOLDER={bindPassword}
INFO_KEYSTORE_PWD_PLACEHOLDER={keyStorePassword}
INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER={path}
INFO_TRUSTSTORE_PWD_PLACEHOLDER={trustStorePassword}
INFO_NICKNAME_PLACEHOLDER={nickname}
INFO_PROXYAUTHID_PLACEHOLDER={authzID}
INFO_SASL_OPTION_PLACEHOLDER={name=value}
INFO_PROTOCOL_VERSION_PLACEHOLDER={version}
INFO_PROP_FILE_PATH_PLACEHOLDER={propertiesFilePath}
INFO_NUM_ENTRIES_PLACEHOLDER={numEntries}
INFO_LDAP_CONTROL_PLACEHOLDER={controloid[:criticality[:value|::b64value|:<filePath]]}
INFO_ENCODING_PLACEHOLDER={encoding}
INFO_SEARCH_SCOPE_PLACEHOLDER={searchScope}
INFO_KEYSTORE_PWD_FILE_PLACEHOLDER={keyStorePasswordFile}
INFO_PATH_PLACEHOLDER={path}
INFO_CONFIGCLASS_PLACEHOLDER={configClass}
INFO_CONFIGFILE_PLACEHOLDER={configFile}
INFO_ADMINUID_PLACEHOLDER={adminUID}
ERR_CANNOT_READ_TRUSTSTORE=Cannot access trust store '%s'.  Verify \
 that the provided trust store exists and that you have read access rights to it
ERR_CANNOT_READ_KEYSTORE=Cannot access key store '%s'.  Verify \
 that the provided key store exists and that you have read access rights to it
INFO_DESCRIPTION_ADMIN_PORT=Directory server administration port number
INFO_DESCRIPTION_ADMIN_BINDDN=Administrator user bind DN
INFO_ERROR_EMPTY_RESPONSE=ERROR: a response must be provided in order to continue
 #
 # MakeLDIF tool
 #
INFO_DESCRIPTION_QUIET=Use quiet mode
INFO_DESCRIPTION_NO_PROMPT=Use non-interactive mode.  If data in \
the command is missing, the user is not prompted and the tool will fail
INFO_OPTION_ACCEPT_LICENSE=Automatically accepts the product license \
(if present)
#
# Setup messages
#
INFO_ARGUMENT_DESCRIPTION_CLI=Use the command line install. \
 If not specified the graphical interface will be launched.  The rest of the \
 options (excluding help and version) will only be taken into account if this \
 option is specified
INFO_ARGUMENT_DESCRIPTION_BASEDN=Base DN for user \
 information in the Directory Server.  Multiple base DNs may be provided by \
 using this option multiple times
INFO_ARGUMENT_DESCRIPTION_ADDBASE=Indicates whether to create the base \
 entry in the Directory Server database
INFO_LDIFFILE_PLACEHOLDER={ldifFile}
INFO_REJECT_FILE_PLACEHOLDER={rejectFile}
INFO_SKIP_FILE_PLACEHOLDER={skipFile}
INFO_JMXPORT_PLACEHOLDER={jmxPort}
INFO_ROOT_USER_DN_PLACEHOLDER={rootUserDN}
INFO_ROOT_USER_PWD_PLACEHOLDER={rootUserPassword}
INFO_ROOT_USER_PWD_FILE_PLACEHOLDER={rootUserPasswordFile}
INFO_TIMEOUT_PLACEHOLDER={timeout}
INFO_GENERAL_DESCRIPTION_REJECTED_FILE=Write rejected entries to the \
 specified file
INFO_GENERAL_DESCRIPTION_SKIPPED_FILE=Write skipped entries to the \
 specified file
INFO_SETUP_DESCRIPTION_SAMPLE_DATA=Specifies that the database should \
 be populated with the specified number of sample entries
INFO_ARGUMENT_DESCRIPTION_LDAPPORT=Port on which the \
 Directory Server should listen for LDAP communication
INFO_ARGUMENT_DESCRIPTION_ADMINCONNECTORPORT=Port on which the \
 Administration Connector should listen for communication
INFO_ARGUMENT_DESCRIPTION_SKIPPORT=Skip the check to determine whether \
 the specified ports are usable
INFO_ARGUMENT_DESCRIPTION_ROOTDN=DN for the initial root \
 user for the Directory Server
INFO_ARGUMENT_DESCRIPTION_ROOTPWFILE=Path to a file \
 containing the password for the initial root user for the Directory Server
 INFO_ARGUMENT_DESCRIPTION_ENABLE_WINDOWS_SERVICE=Enable the server to run \
 as a Windows Service
INFO_ARGUMENT_DESCRIPTION_LDAPSPORT=Port on which the \
 Directory Server should listen for LDAPS communication.  The LDAPS port will \
 be configured and SSL will be enabled only if this argument is explicitly \
 specified
INFO_ARGUMENT_DESCRIPTION_HOST_NAME=The fully-qualified directory server \
 host name that will be used when generating self-signed \
 certificates for LDAP SSL/StartTLS, the administration connector, and \
 replication
INFO_ARGUMENT_DESCRIPTION_USE_SELF_SIGNED_CERTIFICATE=Generate a \
 self-signed certificate that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
INFO_ARGUMENT_DESCRIPTION_USE_PKCS11=Use a certificate in a \
 PKCS#11 token that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
INFO_ARGUMENT_DESCRIPTION_USE_JAVAKEYSTORE=Path of a Java \
 Key Store (JKS) containing a certificate to be used as the server certificate
INFO_ARGUMENT_DESCRIPTION_USE_JCEKS=Path of a JCEKS containing a \
 certificate to be used as the server certificate
INFO_ARGUMENT_DESCRIPTION_USE_PKCS12=Path of a PKCS#12 key \
 store containing the certificate that the server should use when accepting \
 SSL-based connections or performing StartTLS negotiation
INFO_ARGUMENT_DESCRIPTION_CERT_NICKNAME=Nickname of the \
 certificate that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
INFO_ARGUMENT_DESCRIPTION_KEYSTOREPASSWORD=Certificate key store PIN.  \
 A PIN is required when you specify to use an existing certificate \
 as server certificate
INFO_ARGUMENT_DESCRIPTION_KEYSTOREPASSWORD_FILE=Certificate key store \
 PIN file.  A PIN is required when you specify to use an existing certificate \
 as server certificate
INFO_SETUP_DESCRIPTION_DO_NOT_START=Do not start the server when the \
 configuration is completed
INFO_SETUP_DESCRIPTION_ENABLE_STARTTLS=Enable StartTLS to allow \
 secure communication with the server using the LDAP port
#
# SubCommandes messages
#
ERR_ARG_SUBCOMMAND_DUPLICATE_SUBCOMMAND=The argument parser already \
 has a %s subcommand
ERR_ARG_SUBCOMMAND_DUPLICATE_ARGUMENT_NAME=There are multiple \
 arguments for subcommand %s with name %s
ERR_ARG_SUBCOMMAND_ARGUMENT_GLOBAL_CONFLICT=Argument %s for \
 subcommand %s conflicts with a global argument with the same name
ERR_ARG_SUBCOMMAND_DUPLICATE_SHORT_ID=Argument %s for subcommand %s \
 has a short identifier -%s that conflicts with that of argument %s
ERR_ARG_SUBCOMMAND_ARGUMENT_SHORT_ID_GLOBAL_CONFLICT=Argument %s \
 for subcommand %s has a short ID -%s that conflicts with that of global \
 argument %s
ERR_ARG_SUBCOMMAND_DUPLICATE_LONG_ID=Failed to add Argument %s for subcommand %s \
 because there is already an argument with the same identifier for this subcommand
ERR_ARG_SUBCOMMAND_ARGUMENT_LONG_ID_GLOBAL_CONFLICT=Failed to add Argument %s for \
 subcommand %s because there is already a global argument defined with the \
 same long identifier
ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_NAME=There is already another \
 global argument named "%s"
ERR_SUBCMDPARSER_GLOBAL_ARG_NAME_SUBCMD_CONFLICT=The argument name \
 %s conflicts with the name of another argument associated with the %s \
 subcommand
ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_SHORT_ID=Short ID -%s for \
 global argument %s conflicts with the short ID of another global argument %s
ERR_SUBCMDPARSER_GLOBAL_ARG_SHORT_ID_CONFLICT=Short ID -%s for \
 global argument %s conflicts with the short ID for the %s argument associated \
 with subcommand %s
ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_LONG_ID=Failed to add global argument \
 %s because there is already one defined with the same long identifier
ERR_SUBCMDPARSER_GLOBAL_ARG_LONG_ID_CONFLICT=Failed to add argument %s to \
 subcommand %s because there is already one argument with the same long identifier \
 associated to this subcommand.
ERR_SUBCMDPARSER_LONG_ARG_WITHOUT_NAME=The provided command-line \
 argument %s does not contain an argument name
ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID=The provided \
 argument --%s is not a valid global argument identifier
ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_LONG_ID=The provided argument --%s \
 is not a valid global or subcommand argument identifier
ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID=Command-line \
 argument --%s requires a value but none was given
ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID=The provided value \
 "%s" for argument --%s is not acceptable:  %s
ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_LONG_ID=The argument --%s was \
 included multiple times in the provided set of arguments but it does not \
 allow multiple values
ERR_SUBCMDPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE=A value was \
 provided for argument --%s but that argument does not take a value
ERR_SUBCMDPARSER_INVALID_DASH_AS_ARGUMENT=The dash character by \
 itself is invalid for use as an argument name
ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID=The provided \
 argument -%s is not a valid global argument identifier
ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID=The provided argument \
 -%s is not a valid global or subcommand argument identifier
ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID=Argument -%s \
 requires a value but none was provided
ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID=The provided \
 value "%s" for argument -%s is not acceptable:  %s
ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_SHORT_ID=The argument -%s was \
 included multiple times in the provided set of arguments but it does not \
 allow multiple values
ERR_SUBCMDPARSER_CANT_MIX_ARGS_WITH_VALUES=The provided argument \
 block '-%s%s' is illegal because the '%s' argument requires a value but is in \
 the same block as at least one other argument that does not require a value
ERR_SUBCMDPARSER_INVALID_ARGUMENT=The provided argument "%s" is \
 not recognized
ERR_INCOMPATIBLE_JAVA_VERSION=The minimum Java version required is %s.%n%n\
 The detected version is %s.%nThe binary detected is %s%n%nPlease set \
 OPENDJ_JAVA_HOME to the root of a compatible Java installation or edit the \
 java.properties file and then run the dsjavaproperties script to specify the \
 java version to be used.
INFO_DESCRIPTION_CONNECTION_TIMEOUT=Maximum length of time (in \
 milliseconds) that can be taken to establish a connection.  Use '0' to \
 specify no time out
ERR_MENU_BAD_CHOICE_MULTI=Invalid response. Please enter one or \
more valid menu options
ERR_MENU_BAD_CHOICE_SINGLE=Invalid response. Please enter a valid \
menu option
ERR_MENU_BAD_CHOICE_MULTI_DUPE=The option "%s" was specified \
more than once. Please enter one or more valid menu options
INFO_MENU_PROMPT_MULTI_DEFAULT=Enter one or more choices separated by commas [%s]:
INFO_MENU_PROMPT_MULTI=Enter one or more choices separated by commas:
INFO_MENU_PROMPT_SINGLE_DEFAULT=Enter choice [%s]:
INFO_MENU_PROMPT_SINGLE=Enter choice:
INFO_MENU_PROMPT_CONFIRM=%s (%s / %s) [%s]:
INFO_MENU_OPTION_HELP=help
INFO_MENU_OPTION_HELP_KEY=?
INFO_MENU_OPTION_CANCEL=cancel
INFO_MENU_OPTION_CANCEL_KEY=c
INFO_MENU_OPTION_QUIT=quit
INFO_MENU_OPTION_QUIT_KEY=q
INFO_MENU_NUMERIC_OPTION=%d)
INFO_MENU_CHAR_OPTION=%c)
INFO_MENU_OPTION_BACK=back
INFO_MENU_OPTION_BACK_KEY=b
INFO_GENERAL_NO=no
INFO_GENERAL_YES=yes
ERR_CONSOLE_APP_CONFIRM=Invalid response. Please enter \
 "%s" or "%s"
ERR_TRIES_LIMIT_REACHED=Input tries limit reached (%d)
ERR_BAD_PORT_NUMBER=Invalid port number "%s". Please \
  enter a valid port number between 1 and 65535
INFO_OPERATION_START_TIME_MESSAGE=Operation date: %s
INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER=Error reading data from \
 server %s.  There is an error with the certificate presented by the \
 server.\nDetails: %s
INFO_CANNOT_CONNECT_TO_REMOTE_AUTHENTICATION=The provided credentials are not \
 valid in server %s.  Details: %s
INFO_CANNOT_CONNECT_TO_REMOTE_PERMISSIONS=You do not have enough access \
 rights to read the configuration in %s. %nProvide credentials with enough \
 rights.  Details: %s
ERR_CANNOT_CONNECT_TO_REMOTE_COMMUNICATION=Could not connect to \
 %s. Check that the server is running and that it is accessible \
 from the local machine.  Details: %s
INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC=Could not connect to %s.  Check that the \
 server is running and that the provided credentials are valid.%nError \
 details:%n%s
ERR_CONFIRMATION_TRIES_LIMIT_REACHED=Confirmation tries limit reached (%d)
INFO_DESCRIPTION_DISPLAY_EQUIVALENT=Display the equivalent \
 non-interactive argument in the standard output when this command is run in \
 interactive mode
INFO_DESCRIPTION_ADVANCED=Allows the configuration of advanced \
 components and properties
INFO_DESCRIPTION_REMOTE=Connect to a remote server
INFO_DESCRIPTION_CONFIG_CLASS=The fully-qualified name of the Java class \
 to use as the Directory Server configuration handler.  If this is not \
 provided, then a default of org.opends.server.extensions.ConfigFileHandler \
 will be used
INFO_DESCRIPTION_CONFIG_FILE=Path to the Directory Server \
 configuration file
INFO_LDAPAUTH_PASSWORD_PROMPT=Password for user '%s':
#
# Uninstall messages
#
#
# Connection messages
#
INFO_EXCEPTION_OUT_OF_MEMORY_DETAILS=Not enough memory to perform the \
 operation.  Details: %s
INFO_EXCEPTION_DETAILS=Details: %s
INFO_LDAP_CONN_PROMPT_SECURITY_SERVER_CERTIFICATE=Server Certificate:
INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE=%s
INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION=Do you trust this server certificate?
INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_NO=No
INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_SESSION=Yes, for this session only
INFO_LDAP_CONN_PROMPT_SECURITY_TRUST_OPTION_ALWAYS=Yes, also add it to a truststore
INFO_LDAP_CONN_PROMPT_SECURITY_CERTIFICATE_DETAILS=View certificate details
INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_USER_DN=User DN  : %s
INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_VALIDITY=Validity : From '%s'%n             To '%s'
INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE_ISSUER=Issuer   : %s
INFO_LDAP_CONN_HEADING_CONNECTION_PARAMETERS=>>>> Specify OpenDJ LDAP \
  connection parameters
ERR_ERROR_CANNOT_READ_PASSWORD=Unable to read password
ERR_ERROR_CANNOT_READ_BIND_NAME=Unable to read bind name
ERR_ERROR_CANNOT_READ_HOST_NAME=Cannot read the host name
# Strings for generated reference documentation.
REF_TITLE_DESCRIPTION=Description
REF_TITLE_OPTIONS=Options
REF_INTRO_OPTIONS=The <command>%s</command> command takes the following options:
REF_DEFAULT=Default: %s
REF_TITLE_SUBCOMMANDS=Subcommands
REF_INTRO_SUBCOMMANDS=The <command>%s</command> command supports the following subcommands:
REF_PART_TITLE_SUBCOMMANDS=%s Subcommands Reference
REF_PART_INTRO_SUBCOMMANDS=This section covers <command>%s</command> subcommands.
REF_DEFAULT_BACKEND_TYPE=Default: <literal>je</literal> for standard edition, \
  <literal>pdb</literal> for OEM edition.
# Supplements to descriptions for generated reference documentation.
SUPPLEMENT_DESCRIPTION_CONTROLS=<xinclude:include href="variablelist-ldap-controls.xml" />
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ca_ES.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=ERROR:  Potser nou heu introdu\u00eft ambd\u00f3s arguments %s i %s al mateix cop
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_de.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=Sie haben m\u00f6glicherweise nicht beide Argumente --%s und --%s angegeben
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_es.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=No se pueden proporcionar los argumentos --%s y --%s conjuntamente
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_fr.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=Vous ne pouvez pas utiliser \u00e0 la fois les arguments --%s et --%s
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ja.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=--%s \u5f15\u6570\u3068 --%s \u5f15\u6570\u306e\u4e21\u65b9\u306f\u6307\u5b9a\u3067\u304d\u307e\u305b\u3093
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_ko.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=--%s \uc778\uc218\uc640 --%s \uc778\uc218\ub97c \ubaa8\ub450 \uc81c\uacf5\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_pl.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=B\u0141\u0104D\:  Nie mo\u017cesz poda\u0107 obydwu arument\u00f3w %s i %s w tym samym czasie
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_zh_CN.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=\u4e0d\u80fd\u540c\u65f6\u63d0\u4f9b --%s \u548c --%s \u53c2\u6570
opendj-sdk/opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli_zh_TW.properties
New file
@@ -0,0 +1,17 @@
#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
#  Copyright 2016 ForgeRock AS.
#
ERR_TOOL_CONFLICTING_ARGS=\u60a8\u7121\u6cd5\u540c\u6642\u63d0\u4f9b --%s \u8207 --%s \u5f15\u6578
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgAppendProps.ftl
New file
@@ -0,0 +1,24 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<refsect1 xml:id="${id}">
  <title>${title}</title>
  <para>
   ${intro}
  </para>
  ${list}
</refsect1>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgListItem.ftl
New file
@@ -0,0 +1,25 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<listitem>
 <para>
  <link
   <#-- Link to the Reference. Change this if the pages move to another document. -->
   xlink:href="reference#${id}"
   xlink:role="http://docbook.org/xlink/role/olink"
   xlink:show="new"
  ><command>${name}</command></link>: ${description}
 </para>
</listitem>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgListSubtypes.ftl
New file
@@ -0,0 +1,45 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<variablelist>
 <para>
   ${dependencies}
 </para>
 <para>
   ${typesIntro}
 </para>
 <#list children as child>
   <varlistentry>
     <term>${child.name}</term>
     <listitem>
       <para>
         ${child.default}
       </para>
       <para>
         ${child.enabled}
       </para>
       <para>
         ${child.link}
       </para>
     </listitem>
   </varlistentry>
 </#list>
</variablelist>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgReference.ftl
New file
@@ -0,0 +1,35 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
${marker}
<reference xml:id="${name}-subcommands-ref"
           xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="${locale}"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://docbook.org/ns/docbook
                               http://docbook.org/xml/5.0/xsd/docbook.xsd"
           xmlns:xinclude="http://www.w3.org/2001/XInclude">
 <title>${title}</title>
 <partintro>
  <para>
   ${partintro}
  </para>
 </partintro>
 <#list subcommands as subcommand>
 <xinclude:include href="man-${subcommand.id}.xml" />
 </#list>
</reference>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgSubcommand.ftl
New file
@@ -0,0 +1,97 @@
${marker}
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2011-${year} ForgeRock AS.
-->
<refentry xml:id="${id}"
          xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="${locale}"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://docbook.org/ns/docbook
                              http://docbook.org/xml/5.0/xsd/docbook.xsd"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xinclude="http://www.w3.org/2001/XInclude">
 <info>
  <copyright>
   <year>2011-${year}</year>
   <holder>ForgeRock AS.</holder>
  </copyright>
 </info>
 <refmeta>
  <refentrytitle>${name}</refentrytitle><manvolnum>1</manvolnum>
  <refmiscinfo class="software">OpenDJ</refmiscinfo>
  <refmiscinfo class="version">${r"${project.version}"}</refmiscinfo>
 </refmeta>
 <refnamediv>
  <refname>${name}</refname>
  <refpurpose>${purpose}</refpurpose>
 </refnamediv>
 <refsynopsisdiv>
  <cmdsynopsis>
   <command>${name}</command>
   <arg choice="plain">${args}</arg>
  </cmdsynopsis>
 </refsynopsisdiv>
 <refsect1 xml:id="${id}-description">
  <title>${descTitle}</title>
  <para>
   ${description?ensure_ends_with(".")}
  </para>
  <#if info??>${info}</#if>
 </refsect1>
 <#if options??>
 <refsect1 xml:id="${id}-options">
  <title>${optionsTitle}</title>
  <variablelist>
   <para>
    ${optionsIntro}
   </para>
   <#list options as option>
   <varlistentry>
    <term><option>${option.synopsis?xml}</option></term>
    <listitem>
     <para>
      ${option.description?ensure_ends_with(".")}
     </para>
     <#if option.info??>
       <#if option.info.usage??>${option.info.usage}</#if>
       <#if option.info.default??>
       <para>
        ${option.info.default}
       </para>
       </#if>
       <#if option.info.doc??>${option.info.doc}</#if>
     </#if>
    </listitem>
   </varlistentry>
   </#list>
  </variablelist>
 </refsect1>
 </#if>
 <#if propertiesInfo??>${propertiesInfo}</#if>
</refentry>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgVarListEntry.ftl
New file
@@ -0,0 +1,21 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<varlistentry>
  <term>${term}</term>
  <listitem>
    ${definition}
  </listitem>
</varlistentry>
opendj-sdk/opendj-cli/src/main/resources/templates/dscfgVariableList.ftl
New file
@@ -0,0 +1,40 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<variablelist>
<#list properties as property>
  <varlistentry>
    <term>${property.term}</term>
    <listitem>
      <variablelist>
        <varlistentry>
          <term>${property.descTitle}</term>
          <listitem>
            <para>
              ${property.description}
            </para>
          </listitem>
        </varlistentry>
        ${property.list}
      </variablelist>
    </listitem>
  </varlistentry>
</#list>
</variablelist>
opendj-sdk/opendj-cli/src/main/resources/templates/optionsRefSect1.ftl
New file
@@ -0,0 +1,51 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<refsect1 xml:id="${name}-options">
  <title>${title}</title>
  <para>
   ${intro}
  </para>
  <#list groups as group>
    <variablelist>
    <#if group.description??>
      <para>
       ${group.description}
      </para>
    </#if>
    <#list group.options as option>
      <varlistentry>
        <term><option>${option.synopsis?xml}</option></term>
        <listitem>
          <para>
            ${option.description?ensure_ends_with(".")}
          </para>
          <#if option.default??>
            <para>
              ${option.default}
            </para>
          </#if>
          <#if option.info??>${option.info}</#if>
        </listitem>
      </varlistentry>
    </#list>
    </variablelist>
  </#list>
</refsect1>
opendj-sdk/opendj-cli/src/main/resources/templates/refEntry.ftl
New file
@@ -0,0 +1,86 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2011-${year} ForgeRock AS.
-->
<refentry xml:id="${name}-1"
          xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="${locale}"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://docbook.org/ns/docbook
                              http://docbook.org/xml/5.0/xsd/docbook.xsd"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xinclude="http://www.w3.org/2001/XInclude">
 <info>
  <copyright>
   <year>2011-${year}</year>
   <holder>ForgeRock AS.</holder>
  </copyright>
 </info>
 <refmeta>
  <refentrytitle>${name}</refentrytitle><manvolnum>1</manvolnum>
  <refmiscinfo class="software">OpenDJ</refmiscinfo>
  <refmiscinfo class="version">${r"${project.version}"}</refmiscinfo>
 </refmeta>
 <refnamediv>
  <refname>${name}</refname>
  <refpurpose>${shortDesc}</refpurpose>
 </refnamediv>
 <refsynopsisdiv>
  <cmdsynopsis>
   <command>${name}</command>
   <#if args??><arg choice="plain">${args}</arg></#if>
  </cmdsynopsis>
 </refsynopsisdiv>
 <refsect1 xml:id="${name}-description">
   <title>${descTitle}</title>
   <para>
     ${description?ensure_ends_with(".")}
   </para>
   <#if info??>${info}</#if>
 </refsect1>
 <#if optionSection??>
   ${optionSection}
 </#if>
 <#if subcommands??>
   ${subcommands}
 </#if>
 <#if trailingSectionString??>
   ${trailingSectionString}
 </#if>
</refentry>
opendj-sdk/opendj-cli/src/main/resources/templates/refSect1.ftl
New file
@@ -0,0 +1,32 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<refsect1 xml:id="${name}-subcommands">
  <title>${title}</title>
  <#if info??>
    ${info}
  </#if>
  <para>
   ${intro}
  </para>
  <#if isItemizedList??><itemizedlist></#if>
  <#list subcommands as subcommand>
   ${subcommand}
  </#list>
  <#if isItemizedList??></itemizedlist></#if>
</refsect1>
opendj-sdk/opendj-cli/src/main/resources/templates/refSect2.ftl
New file
@@ -0,0 +1,65 @@
<#--
 # The contents of this file are subject to the terms of the Common Development and
 # Distribution License (the License). You may not use this file except in compliance with the
 # License.
 #
 # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 # specific language governing permission and limitations under the License.
 #
 # When distributing Covered Software, include this CDDL Header Notice in each file and include
 # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 # Header, with the fields enclosed by brackets [] replaced by your own identifying
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2015 ForgeRock AS.
 #-->
<refsect2 xml:id="${id}">
  <title>${name}</title>
  <para>
   ${description?ensure_ends_with(".")}
  </para>
  <#if info??>${info}</#if>
  <#if options??>
    <refsect3 xml:id="${id}-options">
      <title>${optionsTitle}</title>
      <variablelist>
        <para>
         ${optionsIntro}
        </para>
        <#list options as option>
          <varlistentry>
            <term><option>${option.synopsis?xml}</option></term>
            <listitem>
             <para>
               ${option.description?ensure_ends_with(".")}
             </para>
             <#if option.info??>
               <#if option.info.usage??>${option.info.usage}</#if>
               <#if option.info.default??>
                  <para>
                    ${option.info.default}
                  </para>
               </#if>
               <#if option.info.doc??>${option.info.doc}</#if>
             </#if>
            </listitem>
          </varlistentry>
        </#list>
      </variablelist>
    </refsect3>
  </#if>
  <#if propertiesInfo??>
    ${propertiesInfo}
  </#if>
</refsect2>
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/CliTestCase.java
New file
@@ -0,0 +1,28 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import org.forgerock.testng.ForgeRockTestCase;
import org.testng.annotations.Test;
/**
 * An abstract class that all CLI unit tests should extend.
 */
@Test(groups = { "precommit", "cli", "sdk" })
public abstract class CliTestCase extends ForgeRockTestCase {
}
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/ConsoleApplicationTestCase.java
New file
@@ -0,0 +1,195 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import org.forgerock.i18n.LocalizableMessage;
import org.testng.annotations.Test;
import static org.fest.assertions.Assertions.assertThat;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/** Unit tests for the console application class. */
@SuppressWarnings("javadoc")
public class ConsoleApplicationTestCase extends CliTestCase {
    final LocalizableMessage msg = LocalizableMessage.raw("Language is the source of misunderstandings.");
    final LocalizableMessage msg2 = LocalizableMessage
            .raw("If somebody wants a sheep, that is a proof that one exists.");
    /** For test purposes only. */
    private static class MockConsoleApplication extends ConsoleApplication {
        private static ByteArrayOutputStream out;
        private static ByteArrayOutputStream err;
        private boolean verbose;
        private boolean interactive;
        private boolean quiet;
        private MockConsoleApplication(PrintStream out, PrintStream err) {
            super(out, err);
        }
        static MockConsoleApplication getDefault() {
            out = new ByteArrayOutputStream();
            final PrintStream psOut = new PrintStream(out);
            err = new ByteArrayOutputStream();
            final PrintStream psErr = new PrintStream(err);
            return new MockConsoleApplication(psOut, psErr);
        }
        public String getOut() throws UnsupportedEncodingException {
            return out.toString("UTF-8");
        }
        public String getErr() throws UnsupportedEncodingException {
            return err.toString("UTF-8");
        }
        @Override
        public boolean isVerbose() {
            return verbose;
        }
        @Override
        public boolean isInteractive() {
            return interactive;
        }
        @Override
        public boolean isQuiet() {
            return quiet;
        }
        public void setVerbose(boolean v) {
            verbose = v;
        }
        public void setInteractive(boolean inter) {
            interactive = inter;
        }
        public void setQuiet(boolean q) {
            quiet = q;
        }
        @Override
        public boolean isMenuDrivenMode() {
            return false;
        }
    }
    @Test
    public void testWriteLineInOutputStream() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        ca.print(msg);
        assertThat(ca.getOut()).contains(msg.toString());
        assertThat(ca.getErr()).isEmpty();
    }
    @Test
    public void testWriteLineInErrorStream() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        ca.errPrintln(msg);
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).contains(msg.toString());
    }
    @Test
    public void testWriteOutputStreamVerbose() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        ca.printVerboseMessage(msg);
        assertThat(ca.isVerbose()).isFalse();
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).isEmpty();
        ca.setVerbose(true);
        ca.printVerboseMessage(msg);
        assertThat(ca.isVerbose()).isTrue();
        assertThat(ca.getOut()).contains(msg.toString());
        assertThat(ca.getErr()).isEmpty();
    }
    @Test
    public void testWriteErrorStreamVerbose() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        ca.errPrintVerboseMessage(msg);
        assertThat(ca.isVerbose()).isFalse();
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).isEmpty();
        ca.setVerbose(true);
        ca.errPrintVerboseMessage(msg);
        assertThat(ca.isVerbose()).isTrue();
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).contains(msg.toString());
    }
    /**
     * In non interactive applications, standard messages should be displayed in the stdout(info) and errors to the
     * stderr (warnings, errors).
     *
     * @throws UnsupportedEncodingException
     */
    @Test
    public void testNonInteractiveApplicationShouldNotStdoutErrors() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        assertFalse(ca.isInteractive());
        ca.errPrintln(msg);
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).contains(msg.toString());
        ca.println(msg2);
        assertThat(ca.getOut()).contains(msg2.toString());
        assertThat(ca.getErr()).doesNotContain(msg2.toString());
    }
    /**
     * If an application is interactive, all messages should be redirect to the stdout. (info, warnings, errors).
     *
     * @throws UnsupportedEncodingException
     */
    @Test
    public void testInteractiveApplicationShouldStdoutErrors() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        assertFalse(ca.isInteractive());
        ca.setInteractive(true);
        assertTrue(ca.isInteractive());
        ca.errPrintln(msg);
        assertThat(ca.getOut()).contains(msg.toString());
        assertThat(ca.getErr()).isEmpty();
        ca.println(msg2);
        assertThat(ca.getOut()).contains(msg2.toString());
        assertThat(ca.getErr()).isEmpty();
    }
    /**
     * In quiet mode, only the stderr should contain lines.
     * @throws UnsupportedEncodingException
     */
    @Test
    public void testQuietMode() throws UnsupportedEncodingException {
        final MockConsoleApplication ca = MockConsoleApplication.getDefault();
        ca.setQuiet(true);
        assertTrue(ca.isQuiet());
        ca.println(msg);
        ca.errPrintln(msg2);
        assertThat(ca.getOut()).isEmpty();
        assertThat(ca.getErr()).contains(msg2.toString());
        assertThat(ca.getErr()).doesNotContain(msg.toString());
    }
}
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/TestSubCommandArgumentParserTestCase.java
New file
@@ -0,0 +1,160 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.ArrayList;
import java.util.List;
import org.fest.assertions.Assertions;
import org.forgerock.i18n.LocalizableMessage;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * Unit tests for the SubCommand class.
 */
@SuppressWarnings("javadoc")
public final class TestSubCommandArgumentParserTestCase extends CliTestCase {
    private SubCommandArgumentParser parser;
    /** First sub-command. */
    private SubCommand sc1;
    /** Second sub-command. */
    private SubCommand sc2;
    /**
     * Create the sub-commands and parser.
     *
     * @throws Exception
     *             If something unexpected happened.
     */
    @BeforeClass
    public void setup() throws Exception {
        parser = new SubCommandArgumentParser(getClass().getName(), LocalizableMessage.raw("test description"), true);
        sc1 = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("sub-command1"));
        sc2 = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                             LocalizableMessage.raw("sub-command2"));
    }
    /**
     * Test the getSubCommand method.
     *
     * @throws Exception
     *             If something unexpected happened.
     */
    @Test
    public void testGetSubCommand() throws Exception {
        Assert.assertSame(parser.getSubCommand("sub-command1"), sc1);
        Assert.assertSame(parser.getSubCommand("sub-command2"), sc2);
        Assert.assertNull(parser.getSubCommand("sub-command3"));
    }
    /**
     * Provide valid command line args.
     *
     * @return Array of valid command line args.
     */
    @DataProvider(name = "validCommandLineArgs")
    public Object[][] createValidCommandLineArgs() {
        return new Object[][] {
            { new String[] {}, null },
            { new String[] { "sub-command1" }, sc1 },
            { new String[] { "sub-command2", "one", "two" }, sc2 },
            { new String[] { "sub-command2", "one", "two", "three" }, sc2 },
            { new String[] { "sub-command2", "one", "two", "three", "four" }, sc2 }, };
    }
    /**
     * Test the parseArguments method with valid args.
     *
     * @param args
     *            The command line args.
     * @param sc
     *            The expected sub-command.
     * @throws Exception
     *             If something unexpected happened.
     */
    @Test(dataProvider = "validCommandLineArgs")
    public void testParseArgumentsWithValidArgs(String[] args, SubCommand sc) throws Exception {
        parser.parseArguments(args);
        // Check the correct sub-command was parsed.
        Assert.assertEquals(parser.getSubCommand(), sc);
        // Check that the trailing arguments were retrieved correctly and
        // in the right order.
        if (args.length > 1) {
            List<String> scargs = new ArrayList<>();
            for (int i = 1; i < args.length; i++) {
                scargs.add(args[i]);
            }
            Assert.assertEquals(parser.getTrailingArguments(), scargs);
        } else {
            Assert.assertTrue(parser.getTrailingArguments().isEmpty());
        }
    }
    /**
     * Provide invalid command line args.
     *
     * @return Array of invalid command line args.
     */
    @DataProvider(name = "invalidCommandLineArgs")
    public Object[][] createInvalidCommandLineArgs() {
        return new Object[][] {
            { new String[] { "sub-command1", "one" } },
            { new String[] { "sub-command1", "one", "two" } },
            { new String[] { "sub-command2" } },
            { new String[] { "sub-command2", "one" } },
            { new String[] { "sub-command2", "one", "two", "three", "four", "five" } }, };
    }
    /**
     * Test the parseArguments method with invalid args.
     *
     * @param args
     *            The command line args.
     * @throws Exception
     *             If something unexpected happened.
     */
    @Test(dataProvider = "invalidCommandLineArgs", expectedExceptions = ArgumentException.class)
    public void testParseArgumentsWithInvalidArgs(String[] args) throws Exception {
        parser.parseArguments(args);
    }
    @DataProvider
    public Object[][] indentAndWrapProvider() throws Exception {
        final String eol = System.getProperty("line.separator");
        return new Object[][] {
            { "test1",                  5, " ", " test1" + eol },
            { "test1 test2",            5, " ", " test1" + eol + " test2" + eol },
            { "test1 test2test3",       5, " ", " test1" + eol + " test2test3" + eol },
            { "test1 test2test3 test4", 5, " ", " test1" + eol + " test2test3" + eol + " test4" + eol },
        };
    }
    @Test(dataProvider = "indentAndWrapProvider")
    public void testIndentAndWrap(String text, int wrapColumn, String indent, String expected) {
        final StringBuilder buffer = new StringBuilder();
        SubCommandArgumentParser.indentAndWrap(indent, buffer, wrapColumn, LocalizableMessage.raw(text));
        Assertions.assertThat(buffer.toString()).isEqualTo(expected);
    }
}
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/TestSubCommandTestCase.java
New file
@@ -0,0 +1,249 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.util.Arrays;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Unit tests for the SubCommand class.
 */
public final class TestSubCommandTestCase extends CliTestCase {
    /**
     * Tests that allowsTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testAllowsTrailingArgumentsFalse1() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("XXX"));
        Assert.assertFalse(sc.allowsTrailingArguments());
    }
    /**
     * Tests that allowsTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testAllowsTrailingArgumentsFalse2() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", false, 0, 0, null, LocalizableMessage.raw("XXX"));
        Assert.assertFalse(sc.allowsTrailingArguments());
    }
    /**
     * Tests that allowsTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testAllowsTrailingArgumentsTrue() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                LocalizableMessage.raw("XXX"));
        Assert.assertTrue(sc.allowsTrailingArguments());
    }
    /**
     * Tests that getMaxTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMaxTrailingArguments1() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMaxTrailingArguments(), 0);
    }
    /**
     * Tests that getMaxTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMaxTrailingArguments2() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", false, 0, 0, null, LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMaxTrailingArguments(), 0);
    }
    /**
     * Tests that getMaxTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMaxTrailingArguments3() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMaxTrailingArguments(), 4);
    }
    /**
     * Tests that getMinTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMinTrailingArguments1() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMinTrailingArguments(), 0);
    }
    /**
     * Tests that getMinTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMinTrailingArguments2() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", false, 0, 0, null, LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMinTrailingArguments(), 0);
    }
    /**
     * Tests that getMinTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetMinTrailingArguments3() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getMinTrailingArguments(), 2);
    }
    /**
     * Tests that getTrailingArgumentsDisplayName works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArgumentsDisplayName1() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("XXX"));
        Assert.assertNull(sc.getTrailingArgumentsDisplayName());
    }
    /**
     * Tests that getTrailingArgumentsDisplayName works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArgumentsDisplayName2() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", false, 0, 0, null, LocalizableMessage.raw("XXX"));
        Assert.assertNull(sc.getTrailingArgumentsDisplayName());
    }
    /**
     * Tests that getTrailingArgumentsDisplayName works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArgumentsDisplayName3() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                LocalizableMessage.raw("XXX"));
        Assert.assertEquals(sc.getTrailingArgumentsDisplayName(), "args1 arg2 [arg3 arg4]");
    }
    /**
     * Tests that getTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArguments1() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command1", LocalizableMessage.raw("XXX"));
        parser.parseArguments(new String[] { "sub-command1" });
        Assert.assertTrue(sc.getTrailingArguments().isEmpty());
    }
    /**
     * Tests that getTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArguments2() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", false, 0, 0, null, LocalizableMessage.raw("XXX"));
        parser.parseArguments(new String[] { "sub-command2" });
        Assert.assertTrue(sc.getTrailingArguments().isEmpty());
    }
    /**
     * Tests that getTrailingArguments works correctly.
     *
     * @throws Exception
     *             If an unexpected problem occurred.
     */
    @Test
    public void testGetTrailingArguments3() throws Exception {
        SubCommandArgumentParser parser = new SubCommandArgumentParser(getClass().getName(),
                LocalizableMessage.raw("test description"), true);
        SubCommand sc = new SubCommand(parser, "sub-command2", true, 2, 4, "args1 arg2 [arg3 arg4]",
                LocalizableMessage.raw("XXX"));
        parser.parseArguments(new String[] { "sub-command2", "arg1", "arg2", "arg3" });
        Assert.assertEquals(sc.getTrailingArguments(), Arrays.asList(new String[] { "arg1", "arg2", "arg3" }));
    }
}
opendj-sdk/opendj-cli/src/test/java/com/forgerock/opendj/cli/UtilsTestCase.java
New file
@@ -0,0 +1,84 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2015 ForgeRock AS.
 */
package com.forgerock.opendj.cli;
import java.io.File;
import java.io.IOException;
import org.testng.annotations.Test;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
@SuppressWarnings("javadoc")
public class UtilsTestCase extends CliTestCase {
    @Test(expectedExceptions = ClientException.class)
    public void testInvalidJavaVersion() throws ClientException {
        final String original = System.getProperty("java.specification.version");
        System.setProperty("java.specification.version", "1.6");
        try {
            Utils.checkJavaVersion();
        } finally {
            System.setProperty("java.specification.version", original);
        }
    }
    @Test
    public void testValidJavaVersion() throws ClientException {
        Utils.checkJavaVersion();
    }
    @Test
    public void testCanWriteOnNewFile() throws ClientException, IOException {
        final File f = File.createTempFile("tempFile", ".txt");
        f.deleteOnExit();
        assertTrue(f.exists());
        assertTrue(Utils.canWrite(f.getPath()));
    }
    @Test
    public void testCannotWriteOnNewFile() throws ClientException, IOException {
        final File f = File.createTempFile("tempFile", ".txt");
        f.setReadOnly();
        f.deleteOnExit();
        assertTrue(f.exists());
        assertFalse(Utils.canWrite(f.getPath()));
    }
    @Test
    public void testGetHostNameForLdapUrl() {
        assertEquals(Utils.getHostNameForLdapUrl("2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx"),
                "[2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]");
        assertEquals(Utils.getHostNameForLdapUrl("basicUrl"), "basicUrl");
        assertEquals(Utils.getHostNameForLdapUrl(null), null);
        // Left/right brackets.
        assertEquals(Utils.getHostNameForLdapUrl("[2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx"),
                "[2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]");
        assertEquals(Utils.getHostNameForLdapUrl("2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]"),
                "[2a01:e35:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]");
    }
    @Test
    public void isDN() {
        assertTrue(Utils.isDN("cn=Jensen,ou=people,dc=example,dc=com"));
        assertTrue(Utils.isDN("cn=John Doe,dc=example,dc=org"));
        assertFalse(Utils.isDN(null));
        assertFalse(Utils.isDN("babs@example.com"));
    }
}
opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
New file
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2014-2016 ForgeRock AS.
-->
<differences>
<!--
For specifying ignored differences, see:
  http://mojo.codehaus.org/clirr-maven-plugin/examples/ignored-differences.html
path/methods/to/from matching can either use:
- regex when surrounded with '%regex[]'
- ant style path matching when surrounded with '%ant[]'
- ant style path matching when not surrounded by anything
For path/methods matching in maven-clirr-plugin see (change version numbers accordingly):
  http://svn.codehaus.org/mojo/tags/clirr-maven-plugin-2.6.1/src/main/java/org/codehaus/mojo/clirr/Difference.java
  http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.plexus/plexus-utils/3.0.7/org/codehaus/plexus/util/SelectorUtils.java
For a description of ant style path expressions see:
  http://ant.apache.org/manual/dirtasks.html#patterns
Note: waiting on https://jira.codehaus.org/browse/MCLIRR-62 to be resolved to avoid the need to use \s* in the '<to>' tags.
-->
</differences>
opendj-sdk/opendj-core/pom.xml
New file
@@ -0,0 +1,312 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  The contents of this file are subject to the terms of the Common Development and
  Distribution License (the License). You may not use this file except in compliance with the
  License.
  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
  specific language governing permission and limitations under the License.
  When distributing Covered Software, include this CDDL Header Notice in each file and include
  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
  Header, with the fields enclosed by brackets [] replaced by your own identifying
  information: "Portions Copyright [year] [name of copyright owner]".
  Copyright 2011-2016 ForgeRock AS.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>opendj-sdk-parent</artifactId>
        <groupId>org.forgerock.opendj</groupId>
        <version>4.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>opendj-core</artifactId>
    <name>OpenDJ Core APIs</name>
    <description>
        This module provides the core APIs required for implementing LDAP Directory
        client and server applications. Unlike the SDK this module does not
        include a default network transport which must be obtained separately.
    </description>
    <packaging>bundle</packaging>
    <dependencies>
        <dependency>
            <groupId>org.forgerock.commons</groupId>
            <artifactId>i18n-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.forgerock.commons</groupId>
            <artifactId>forgerock-util</artifactId>
        </dependency>
        <dependency>
            <groupId>org.forgerock.commons</groupId>
            <artifactId>i18n-slf4j</artifactId>
        </dependency>
        <dependency>
          <groupId>com.github.stephenc.jcip</groupId>
          <artifactId>jcip-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>org.forgerock</groupId>
            <artifactId>forgerock-build-tools</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <properties>
        <opendj.osgi.import.additional>
            com.sun.security.auth*;resolution:=optional
        </opendj.osgi.import.additional>
        <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.forgerock.commons</groupId>
                <artifactId>i18n-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-messages</goal>
                        </goals>
                        <configuration>
                            <messageFiles>
                                <messageFile>com/forgerock/opendj/ldap/core.properties</messageFile>
                            </messageFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- Retrieve the SCM revision number and store it into the ${buildRevision} property -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>buildnumber-maven-plugin</artifactId>
            </plugin>
            <!-- Creates opendj-core bundle -->
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <configuration>
                    <instructions>
                        <Export-Package>
                            com.forgerock.opendj.util,
                            org.forgerock.opendj.io,
                            org.forgerock.opendj.ldap*,
                            org.forgerock.opendj.ldif
                        </Export-Package>
                        <Build-Maven>Apache Maven ${maven.version}</Build-Maven>
                        <SCM-Revision>${buildRevision}</SCM-Revision>
                        <SCM-Branch>${scmBranch}</SCM-Branch>
                        <Build-Time>${maven.build.timestamp}</Build-Time>
                        <Build-Java>${java.version}</Build-Java>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <!-- This profile provides API/ABI compatiblity checks and reports via Clirr -->
            <id>clirr</id>
            <activation>
                <file>
                    <exists>clirr-ignored-api-changes.xml</exists>
                    <!-- this file name is duplicated due to MNG-4471 -->
                </file>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>clirr-maven-plugin</artifactId>
                        <version>${clirrPluginVersion}</version>
                        <inherited>true</inherited>
                        <configuration>
                            <comparisonArtifacts>
                                <comparisonArtifact>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>opendj-ldap-sdk</artifactId>
                                    <!-- former name of this jar -->
                                    <version>3.0.0-SNAPSHOT</version>
                                </comparisonArtifact>
                            </comparisonArtifacts>
                            <excludes>
                                <exclude>com/**</exclude>
                            </excludes>
                            <ignoredDifferencesFile>clirr-ignored-api-changes.xml</ignoredDifferencesFile>
                        </configuration>
                        <executions>
                            <execution>
                                <id>mvn clirr:check</id>
                            </execution>
                            <execution>
                                <id>mvn verify</id>
                                <goals>
                                    <goal>check</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <reporting>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>clirr-maven-plugin</artifactId>
                        <version>${clirrPluginVersion}</version>
                        <inherited>true</inherited>
                        <configuration>
                            <comparisonArtifacts>
                                <comparisonArtifact>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>opendj-ldap-sdk</artifactId>
                                    <!-- former name of this jar -->
                                    <version>2.6.0</version>
                                </comparisonArtifact>
                            </comparisonArtifacts>
                            <excludes>
                                <exclude>com/**</exclude>
                            </excludes>
                            <ignoredDifferencesFile>clirr-ignored-api-changes.xml</ignoredDifferencesFile>
                        </configuration>
                    </plugin>
                </plugins>
            </reporting>
        </profile>
        <!--
          Generates consolidated Javadoc covering both LDAP SDK packages
          and also dependency (and transitive dependency) ForgeRock packages.
        -->
        <profile>
            <id>forgerock-release</id>
            <properties>
                <javadocTitle>OpenDJ LDAP SDK ${project.version} API</javadocTitle>
                <timestamp>${maven.build.timestamp}</timestamp>
                <maven.build.timestamp.format>yyyy</maven.build.timestamp.format>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>javadoc-jar</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <includeDependencySources>true</includeDependencySources>
                            <includeTransitiveDependencySources>true</includeTransitiveDependencySources>
                            <dependencySourceIncludes>
                                <dependencySourceInclude>org.forgerock.*:*</dependencySourceInclude>
                            </dependencySourceIncludes>
                            <excludePackageNames>com.*:*.internal</excludePackageNames>
                            <groups>
                                <group>
                                    <title>${project.name} Packages</title>
                                    <packages>${project.groupId}*</packages>
                                </group>
                                <group>
                                    <title>ForgeRock Common Packages</title>
                                    <packages>*</packages>
                                </group>
                            </groups>
                            <author>false</author>
                            <doctitle>${javadocTitle}</doctitle>
                            <windowtitle>${javadocTitle}</windowtitle>
                            <header>${javadocTitle}</header>
                            <footer>${javadocTitle}</footer>
                            <bottom>Copyright 2011-${maven.build.timestamp} ForgeRock AS.</bottom>
                            <links>
                                <link>http://docs.oracle.com/javase/7/docs/api/</link>
                                <link>http://www.slf4j.org/apidocs/</link>
                            </links>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <reportSets>
                    <reportSet>
                        <reports>
                            <report>dependencies</report>
                        </reports>
                    </reportSet>
                </reportSets>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                    <links>
                        <link>http://commons.forgerock.org/i18n-framework/i18n-core/apidocs</link>
                    </links>
                </configuration>
            </plugin>
        </plugins>
    </reporting>
</project>
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControl.java
New file
@@ -0,0 +1,132 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.controls;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_BAD_OID;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_ACCTUSABLEREQ_CONTROL_HAS_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import org.forgerock.util.Reject;
/**
 * 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>() {
                @Override
                public AccountUsabilityRequestControl decodeControl(final Control control,
                        final DecodeOptions options) throws DecodeException {
                    Reject.ifNull(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;
                }
                @Override
                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;
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public ByteString getValue() {
        return null;
    }
    @Override
    public boolean hasValue() {
        return false;
    }
    @Override
    public boolean isCritical() {
        return isCritical;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControl.java
New file
@@ -0,0 +1,451 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2011-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.controls;
import static com.forgerock.opendj.util.StaticUtils.byteToHex;
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Reader;
import org.forgerock.opendj.io.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import org.forgerock.util.Reject;
/**
 * 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 {
    private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
    /** 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>() {
                @Override
                public AccountUsabilityResponseControl decodeControl(final Control control,
                        final DecodeOptions options) throws DecodeException {
                    Reject.ifNull(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) {
                        logger.debug(LocalizableMessage.raw("%s", e));
                        final LocalizableMessage message =
                                ERR_ACCTUSABLERES_DECODE_ERROR.get(getExceptionMessage(e));
                        throw DecodeException.error(message);
                    }
                }
                @Override
                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;
    }
    @Override
    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;
    }
    @Override
    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);
        }
    }
    @Override
    public boolean hasValue() {
        return true;
    }
    @Override
    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;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/RealAttributesOnlyRequestControl.java
New file
@@ -0,0 +1,130 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.controls;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_REAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_REAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import org.forgerock.util.Reject;
/**
 * 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>() {
                @Override
                public RealAttributesOnlyRequestControl decodeControl(final Control control,
                        final DecodeOptions options) throws DecodeException {
                    Reject.ifNull(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;
                }
                @Override
                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;
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public ByteString getValue() {
        return null;
    }
    @Override
    public boolean hasValue() {
        return false;
    }
    @Override
    public boolean isCritical() {
        return isCritical;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/TransactionIdControl.java
New file
@@ -0,0 +1,131 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.controls;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import org.forgerock.util.Reject;
/**
 * Control to provide a transaction ID.
 * <p>
 * The transaction ID is related to Common Audit : it is used for tracking the processing of a user-interaction as it
 * passes through the Forgerock stack
 * <p>
 * The control's value is the UTF-8 encoding of the transaction ID.
 */
public final class TransactionIdControl implements Control {
    /** OID for this control. */
    public static final String OID = "1.3.6.1.4.1.36733.2.1.5.1";
    /** A decoder which can be used for decoding the simple paged results control. */
    public static final ControlDecoder<TransactionIdControl> DECODER = new ControlDecoder<TransactionIdControl>() {
        @Override
        public TransactionIdControl decodeControl(final Control control, final DecodeOptions options)
                throws DecodeException {
            Reject.ifNull(control);
            if (control instanceof TransactionIdControl) {
                return (TransactionIdControl) control;
            }
            if (!control.getOID().equals(OID)) {
                throw DecodeException.error(ERR_TRANSACTION_ID_CONTROL_BAD_OID.get(control.getOID(), OID));
            }
            if (!control.hasValue()) {
                // The control must always have a value.
                throw DecodeException.error(ERR_TRANSACTION_ID_CONTROL_DECODE_NULL.get());
            }
            return new TransactionIdControl(control.getValue().toString());
        }
        @Override
        public String getOID() {
            return OID;
        }
    };
    /**
     * Creates a new transactionId control.
     *
     * @param transactionId
     *            The transaction id to provide through this control.
     * @return The new control.
     * @throws NullPointerException
     *             If {@code transactionId} was {@code null}.
     */
    public static TransactionIdControl newControl(final String transactionId) {
        Reject.ifNull(transactionId);
        return new TransactionIdControl(transactionId);
    }
    /** The control value transactionId element. */
    private final String transactionId;
    private TransactionIdControl(final String transactionId) {
        this.transactionId = transactionId;
    }
    /**
     * Returns the transaction id.
     *
     * @return The transaction id.
     */
    public String getTransactionId() {
        return transactionId;
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public ByteString getValue() {
        return ByteString.valueOfUtf8(transactionId);
    }
    @Override
    public boolean hasValue() {
        return true;
    }
    @Override
    public boolean isCritical() {
        // This control is never critical.
        return false;
    }
    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("TransactionIdControl(oid=");
        builder.append(getOID());
        builder.append(", transactionId=");
        builder.append(transactionId);
        builder.append(")");
        return builder.toString();
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/VirtualAttributesOnlyRequestControl.java
New file
@@ -0,0 +1,130 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.controls;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_CONTROL_BAD_OID;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.ControlDecoder;
import org.forgerock.util.Reject;
/**
 * 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>() {
                @Override
                public VirtualAttributesOnlyRequestControl decodeControl(final Control control,
                        final DecodeOptions options) throws DecodeException {
                    Reject.ifNull(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;
                }
                @Override
                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;
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public ByteString getValue() {
        return null;
    }
    @Override
    public boolean hasValue() {
        return false;
    }
    @Override
    public boolean isCritical() {
        return isCritical;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/controls/package-info.java
New file
@@ -0,0 +1,21 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 */
/**
 * Classes implementing Sun proprietary LDAP controls.
 */
package com.forgerock.opendj.ldap.controls;
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedRequest.java
New file
@@ -0,0 +1,169 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2013-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Reader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.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> {
        @Override
        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> {
        @Override
        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).setMatchedDN(matchedDN)
                    .setDiagnosticMessage(diagnosticMessage);
        }
        @Override
        public GetConnectionIDExtendedResult decodeExtendedResult(final ExtendedResult result,
                final DecodeOptions options) throws DecodeException {
            if (result instanceof GetConnectionIDExtendedResult) {
                return (GetConnectionIDExtendedResult) result;
            }
            final ResultCode resultCode = result.getResultCode();
            final GetConnectionIDExtendedResult newResult =
                    GetConnectionIDExtendedResult.newResult(resultCode)
                        .setMatchedDN(result.getMatchedDN())
                        .setDiagnosticMessage(result.getDiagnosticMessage());
            final ByteString responseValue = result.getValue();
            if (!resultCode.isExceptional() && responseValue == null) {
                throw DecodeException.error(LocalizableMessage.raw("Empty response value"));
            }
            if (responseValue != null) {
                try {
                    final ASN1Reader reader = ASN1.getReader(responseValue);
                    newResult.setConnectionID((int) reader.readInteger());
                } catch (final IOException e) {
                    throw DecodeException.error(LocalizableMessage
                            .raw("Error decoding response value"), e);
                }
            }
            for (final Control control : result.getControls()) {
                newResult.addControl(control);
            }
            return newResult;
        }
    }
    /**
     * 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.
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public ExtendedResultDecoder<GetConnectionIDExtendedResult> getResultDecoder() {
        return RESULT_DECODER;
    }
    @Override
    public ByteString getValue() {
        return null;
    }
    @Override
    public boolean hasValue() {
        return false;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetConnectionIDExtendedResult.java
New file
@@ -0,0 +1,124 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2012-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import java.io.IOException;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResult;
import org.forgerock.util.Reject;
/**
 * Get connection ID extended result.
 *
 * @see GetConnectionIDExtendedRequest
 */
public final class GetConnectionIDExtendedResult extends
        AbstractExtendedResult<GetConnectionIDExtendedResult> {
    /**
     * Creates a new get connection ID extended result with a default connection
     * ID of -1.
     *
     * @param resultCode
     *            The result code.
     * @return The new get connection ID extended result.
     * @throws NullPointerException
     *             If {@code resultCode} was {@code null}.
     */
    public static GetConnectionIDExtendedResult newResult(final ResultCode resultCode) {
        Reject.ifNull(resultCode);
        return new GetConnectionIDExtendedResult(resultCode);
    }
    private int connectionID = -1;
    private GetConnectionIDExtendedResult(final ResultCode resultCode) {
        super(resultCode);
    }
    /**
     * Returns the client connection ID.
     *
     * @return The client connection ID.
     */
    public int getConnectionID() {
        return connectionID;
    }
    @Override
    public String getOID() {
        return GetConnectionIDExtendedRequest.OID;
    }
    @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();
    }
    @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;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/GetSymmetricKeyExtendedRequest.java
New file
@@ -0,0 +1,228 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2013-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Reader;
import org.forgerock.opendj.io.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.ExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.Responses;
/** Get symmetric key extended request. */
public final class GetSymmetricKeyExtendedRequest extends
        AbstractExtendedRequest<GetSymmetricKeyExtendedRequest, ExtendedResult> {
    private static final class RequestDecoder implements
            ExtendedRequestDecoder<GetSymmetricKeyExtendedRequest, ExtendedResult> {
        @Override
        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 ioe) {
                logger.debug(LocalizableMessage.raw("%s", ioe));
                final LocalizableMessage message =
                        ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION.get(ioe.getMessage());
                throw DecodeException.error(message, ioe);
            }
        }
    }
    private static final class ResultDecoder extends AbstractExtendedResultDecoder<ExtendedResult> {
        @Override
        public ExtendedResult newExtendedErrorResult(final ResultCode resultCode,
                final String matchedDN, final String diagnosticMessage) {
            return Responses.newGenericExtendedResult(resultCode).setMatchedDN(matchedDN)
                    .setDiagnosticMessage(diagnosticMessage);
        }
        @Override
        public ExtendedResult decodeExtendedResult(final ExtendedResult result,
                final DecodeOptions options) throws DecodeException {
            return result;
        }
    }
    private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
    /** 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;
    private String instanceKeyID;
    /** Instantiation via factory. */
    private GetSymmetricKeyExtendedRequest() {
    }
    /**
     * Returns the instance key ID.
     *
     * @return The instance key ID.
     */
    public String getInstanceKeyID() {
        return instanceKeyID;
    }
    @Override
    public String getOID() {
        return OID;
    }
    /**
     * Returns the request symmetric key.
     *
     * @return The request symmetric key.
     */
    public String getRequestSymmetricKey() {
        return requestSymmetricKey;
    }
    @Override
    public ExtendedResultDecoder<ExtendedResult> getResultDecoder() {
        return RESULT_DECODER;
    }
    @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();
    }
    @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;
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedRequest.java
New file
@@ -0,0 +1,696 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2011-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Reader;
import org.forgerock.opendj.io.ASN1Writer;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.AbstractExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequestDecoder;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResultDecoder;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.ExtendedResultDecoder;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.ldap.extensions.PasswordPolicyStateOperationType.*;
import static com.forgerock.opendj.util.StaticUtils.*;
/**
 * 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;
        }
        @Override
        public PasswordPolicyStateOperationType getOperationType() {
            return property;
        }
        @Override
        public Iterable<ByteString> getValues() {
            return values;
        }
        @Override
        public String toString() {
            return property + ": " + values;
        }
    }
    private static final class RequestDecoder
            implements
            ExtendedRequestDecoder<PasswordPolicyStateExtendedRequest, PasswordPolicyStateExtendedResult> {
        @Override
        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();
                newRequest.setTargetUser(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> {
        @Override
        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).setMatchedDN(
                    matchedDN).setDiagnosticMessage(diagnosticMessage);
        }
        @Override
        public PasswordPolicyStateExtendedResult decodeExtendedResult(final ExtendedResult result,
                final DecodeOptions options) throws DecodeException {
            final ResultCode resultCode = result.getResultCode();
            final PasswordPolicyStateExtendedResult newResult =
                    new PasswordPolicyStateExtendedResult(resultCode).setMatchedDN(
                            result.getMatchedDN()).setDiagnosticMessage(
                            result.getDiagnosticMessage());
            final ByteString responseValue = result.getValue();
            if (!resultCode.isExceptional() && responseValue == null) {
                throw DecodeException.error(ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE.get());
            }
            if (responseValue != null) {
                try {
                    final ASN1Reader reader = ASN1.getReader(responseValue);
                    reader.readStartSequence();
                    newResult.setTargetUser(reader.readOctetStringAsString());
                    decodeOperations(reader, newResult);
                    reader.readEndSequence();
                } catch (final IOException ioe) {
                    final LocalizableMessage message =
                            ERR_PWPSTATE_EXTOP_DECODE_FAILURE.get(getExceptionMessage(ioe));
                    throw DecodeException.error(message, ioe);
                }
            }
            for (final Control control : result.getControls()) {
                newResult.addControl(control);
            }
            return newResult;
        }
    }
    /**
     * 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 String targetUser = "";
    private final List<PasswordPolicyStateOperation> operations = new ArrayList<>();
    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<>();
                    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. */
    public PasswordPolicyStateExtendedRequest() {
        // Nothing to do.
    }
    /**
     * Adds the provided authentication failure time to this request.
     *
     * @param date
     *            The authentication failure time.
     */
    public void addAuthenticationFailureTime(final Date date) {
        setDateProperty(ADD_AUTHENTICATION_FAILURE_TIMES, date);
    }
    /**
     * Adds the provided grace login use time to this request.
     *
     * @param date
     *            The grace login use time.
     */
    public void addGraceLoginUseTime(final Date date) {
        setDateProperty(ADD_GRACE_LOGIN_USE_TIME, date);
    }
    @Override
    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);
    }
    @Override
    public String getOID() {
        return OID;
    }
    @Override
    public Iterable<PasswordPolicyStateOperation> getOperations() {
        return operations;
    }
    @Override
    public ExtendedResultDecoder<PasswordPolicyStateExtendedResult> getResultDecoder() {
        return RESULT_DECODER;
    }
    @Override
    public String getTargetUser() {
        return targetUser;
    }
    @Override
    public ByteString getValue() {
        return encode(targetUser, operations);
    }
    @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) {
        setBooleanProperty(SET_ACCOUNT_DISABLED_STATE, state);
    }
    /**
     * Sets the account expiration time.
     *
     * @param date
     *            The account expiration time.
     */
    public void setAccountExpirationTime(final Date date) {
        setDateProperty(SET_ACCOUNT_EXPIRATION_TIME, date);
    }
    /**
     * Sets the authentication failure times.
     *
     * @param dates
     *            The authentication failure times.
     */
    public void setAuthenticationFailureTimes(final Date... dates) {
        setDateProperties(SET_AUTHENTICATION_FAILURE_TIMES, dates);
    }
    /**
     * Sets the grace login use times.
     *
     * @param dates
     *            The grace login use times.
     */
    public void setGraceLoginUseTimes(final Date... dates) {
        setDateProperties(SET_GRACE_LOGIN_USE_TIMES, dates);
    }
    /**
     * Sets the last login time.
     *
     * @param date
     *            The last login time.
     */
    public void setLastLoginTime(final Date date) {
        setDateProperty(SET_LAST_LOGIN_TIME, date);
    }
    /**
     * Sets the password changed by required time.
     *
     * @param state
     *            The password changed by required time.
     */
    public void setPasswordChangedByRequiredTime(final boolean state) {
        setBooleanProperty(SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, state);
    }
    /**
     * Sets the password changed time.
     *
     * @param date
     *            The password changed time.
     */
    public void setPasswordChangedTime(final Date date) {
        setDateProperty(SET_PASSWORD_CHANGED_TIME, date);
    }
    /**
     * Sets the password expiration warned time.
     *
     * @param date
     *            The password expiration warned time.
     */
    public void setPasswordExpirationWarnedTime(final Date date) {
        setDateProperty(SET_PASSWORD_EXPIRATION_WARNED_TIME, date);
    }
    /**
     * Sets the password reset state.
     *
     * @param state
     *            The password reset state.
     */
    public void setPasswordResetState(final boolean state) {
        setBooleanProperty(SET_PASSWORD_RESET_STATE, state);
    }
    private void setBooleanProperty(PasswordPolicyStateOperationType property, final boolean state) {
        operations.add(new MultiValueOperation(property, ByteString.valueOfUtf8(String.valueOf(state))));
    }
    private void setDateProperty(PasswordPolicyStateOperationType property, final Date date) {
        if (date != null) {
            operations.add(new MultiValueOperation(property, toByteString(date)));
        } else {
            operations.add(property);
        }
    }
    private void setDateProperties(PasswordPolicyStateOperationType property, final Date... dates) {
        if (dates == null) {
            operations.add(property);
        } else {
            final ArrayList<ByteString> times = new ArrayList<>(dates.length);
            for (final Date date : dates) {
                times.add(toByteString(date));
            }
            operations.add(new MultiValueOperation(property, times));
        }
    }
    private ByteString toByteString(final Date date) {
        return ByteString.valueOfUtf8(formatAsGeneralizedTime(date));
    }
    @Override
    public void setTargetUser(String targetUser) {
        this.targetUser = targetUser != null ? targetUser : "";
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateExtendedResult.java
New file
@@ -0,0 +1,103 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2015-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.AbstractExtendedResult;
/** The password policy state extended result. */
public final class PasswordPolicyStateExtendedResult extends
        AbstractExtendedResult<PasswordPolicyStateExtendedResult> implements
        PasswordPolicyStateOperationContainer {
    private String targetUser = "";
    private final List<PasswordPolicyStateOperation> operations = new ArrayList<>();
    /**
     * Creates a new password policy state extended result with the provided
     * result code.
     *
     * @param resultCode
     *            The result code.
     */
    public PasswordPolicyStateExtendedResult(final ResultCode resultCode) {
        super(resultCode);
    }
    @Override
    public void addOperation(final PasswordPolicyStateOperation operation) {
        operations.add(operation);
    }
    @Override
    public String getOID() {
        // No response name defined.
        return PasswordPolicyStateExtendedRequest.OID;
    }
    @Override
    public Iterable<PasswordPolicyStateOperation> getOperations() {
        return operations;
    }
    @Override
    public String getTargetUser() {
        return targetUser;
    }
    @Override
    public ByteString getValue() {
        return PasswordPolicyStateExtendedRequest.encode(targetUser, operations);
    }
    @Override
    public boolean hasValue() {
        return true;
    }
    @Override
    public void setTargetUser(String targetUser) {
        this.targetUser = targetUser != null ? targetUser : "";
    }
    @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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperation.java
New file
@@ -0,0 +1,38 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 */
package com.forgerock.opendj.ldap.extensions;
import org.forgerock.opendj.ldap.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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperationContainer.java
New file
@@ -0,0 +1,56 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 */
package com.forgerock.opendj.ldap.extensions;
/**
 * Password policy state operation container.
 */
interface PasswordPolicyStateOperationContainer {
    /**
     * Returns the name of the user targeted by this password policy state
     * operation.
     *
     * @return The name of the user targeted by this password policy state
     *         operation.
     */
    String getTargetUser();
    /**
     * Sets the name of the user targeted by this password policy state
     * operation.
     *
     * @param targetUser
     *            The name of the user targeted by this password policy state
     *            operation.
     */
    void setTargetUser(String targetUser);
    /**
     * 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/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/PasswordPolicyStateOperationType.java
New file
@@ -0,0 +1,186 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.extensions;
import org.forgerock.opendj.ldap.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;
    }
    @Override
    public PasswordPolicyStateOperationType getOperationType() {
        return this;
    }
    @Override
    public Iterable<ByteString> getValues() {
        return null;
    }
    @Override
    public String toString() {
        return propertyName;
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/ldap/extensions/package-info.java
New file
@@ -0,0 +1,21 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009 Sun Microsystems, Inc.
 */
/**
 * Classes implementing Sun proprietary LDAP extended operations.
 */
package com.forgerock.opendj.ldap.extensions;
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java
New file
@@ -0,0 +1,316 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009 Sun Microsystems, Inc.
 * Portions copyright 2011-2016 ForgeRock AS.
 */
package com.forgerock.opendj.util;
/**
 * A {@code ASCIICharProp} provides fast access to ASCII character properties.
 * In particular, the ability to query whether or not a character is a letter, a
 * digit, hexadecimal character, as well as various methods for performing
 * character conversions.
 * <p>
 * The methods in this class do not perform memory allocations nor calculations
 * and so can be used safely in high performance situations.
 */
public final class ASCIICharProp implements Comparable<ASCIICharProp> {
    private final char c;
    private final char upperCaseChar;
    private final char lowerCaseChar;
    private final boolean isUpperCaseChar;
    private final boolean isLowerCaseChar;
    private final boolean isDigit;
    private final boolean isLetter;
    private final boolean isKeyChar;
    private final boolean isCompatKeyChar;
    private final boolean isHexChar;
    private final int hexValue;
    private final int decimalValue;
    private final String stringValue;
    private static final ASCIICharProp[] CHAR_PROPS = new ASCIICharProp[128];
    static {
        for (int i = 0; i < 128; i++) {
            CHAR_PROPS[i] = new ASCIICharProp((char) i);
        }
    }
    /**
     * Returns the character properties for the provided ASCII character. If a
     * non-ASCII character is provided then this method returns {@code null}.
     *
     * @param c
     *            The ASCII character.
     * @return The character properties for the provided ASCII character, or
     *         {@code null} if {@code c} is greater than {@code \u007F} .
     */
    public static ASCIICharProp valueOf(final char c) {
        if (c < 128) {
            return CHAR_PROPS[c];
        } else {
            return null;
        }
    }
    /**
     * Returns the character properties for the provided ASCII character. If a
     * non-ASCII character is provided then this method returns {@code null}.
     *
     * @param c
     *            The ASCII character.
     * @return The character properties for the provided ASCII character, or
     *         {@code null} if {@code c} is less than zero or greater than
     *         {@code \u007F} .
     */
    public static ASCIICharProp valueOf(final int c) {
        if (c >= 0 && c < 128) {
            return CHAR_PROPS[c];
        } else {
            return null;
        }
    }
    private ASCIICharProp(final char c) {
        this.c = c;
        this.stringValue = new String(new char[] { c });
        if (c >= 'a' && c <= 'z') {
            this.upperCaseChar = (char) (c - 32);
            this.lowerCaseChar = c;
            this.isUpperCaseChar = false;
            this.isLowerCaseChar = true;
            this.isDigit = false;
            this.isLetter = true;
            this.isKeyChar = true;
            this.isCompatKeyChar = true;
            this.decimalValue = -1;
            if (c >= 'a' && c <= 'f') {
                this.isHexChar = true;
                this.hexValue = c - 87;
            } else {
                this.isHexChar = false;
                this.hexValue = -1;
            }
        } else if (c >= 'A' && c <= 'Z') {
            this.upperCaseChar = c;
            this.lowerCaseChar = (char) (c + 32);
            this.isUpperCaseChar = true;
            this.isLowerCaseChar = false;
            this.isDigit = false;
            this.isLetter = true;
            this.isKeyChar = true;
            this.isCompatKeyChar = true;
            this.decimalValue = -1;
            if (c >= 'A' && c <= 'F') {
                this.isHexChar = true;
                this.hexValue = c - 55;
            } else {
                this.isHexChar = false;
                this.hexValue = -1;
            }
        } else if (c >= '0' && c <= '9') {
            this.upperCaseChar = c;
            this.lowerCaseChar = c;
            this.isUpperCaseChar = false;
            this.isLowerCaseChar = false;
            this.isDigit = true;
            this.isLetter = false;
            this.isKeyChar = true;
            this.isCompatKeyChar = true;
            this.isHexChar = true;
            this.hexValue = c - 48;
            this.decimalValue = c - 48;
        } else {
            this.upperCaseChar = c;
            this.lowerCaseChar = c;
            this.isUpperCaseChar = false;
            this.isLowerCaseChar = false;
            this.isDigit = false;
            this.isLetter = false;
            this.isKeyChar = c == '-';
            this.isCompatKeyChar = (c == '-') || (c == '.') || (c == '_') || (c == '=');
            this.isHexChar = false;
            this.hexValue = -1;
            this.decimalValue = -1;
        }
    }
    /**
     * Returns the char value associated with this {@code ASCIICharProp}.
     *
     * @return The char value associated with this {@code ASCIICharProp}.
     */
    public char charValue() {
        return c;
    }
    @Override
    public int compareTo(final ASCIICharProp o) {
        return c - o.c;
    }
    /**
     * Returns the decimal value associated with this {@code ASCIICharProp}, or
     * {@code -1} if the value is not a decimal digit.
     *
     * @return The decimal value associated with this {@code ASCIICharProp}, or
     *         {@code -1} if the value is not a decimal digit.
     */
    public int decimalValue() {
        return decimalValue;
    }
    @Override
    public boolean equals(final Object obj) {
        return this == obj;
    }
    @Override
    public int hashCode() {
        return c;
    }
    /**
     * Returns the hexadecimal value associated with this {@code ASCIICharProp}
     * , or {@code -1} if the value is not a hexadecimal digit.
     *
     * @return The hexadecimal value associated with this {@code ASCIICharProp}
     *         , or {@code -1} if the value is not a hexadecimal digit.
     */
    public int hexValue() {
        return hexValue;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is a decimal digit.
     *
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is a decimal digit.
     */
    public boolean isDigit() {
        return isDigit;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is a hexadecimal digit.
     *
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is a hexadecimal digit.
     */
    public boolean isHexDigit() {
        return isHexChar;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is a {@code keychar} as defined in RFC 4512. A
     * {@code keychar} is a letter, a digit, or a hyphen. When
     * {@code allowCompatChars} is {@code true} the following illegal characters
     * will be permitted:
     *
     * <pre>
     * HYPHEN  = %x2D ; hyphen ("-")
     * DOT     = %x2E ; period (".")
     * EQUALS  = %x3D ; equals sign ("=")
     * USCORE  = %x5F ; underscore ("_")
     * </pre>
     *
     * @param allowCompatChars
     *            {@code true} if certain illegal characters should be allowed
     *            for compatibility reasons.
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is a {@code keychar}.
     */
    public boolean isKeyChar(final boolean allowCompatChars) {
        return allowCompatChars ? isCompatKeyChar : isKeyChar;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is a letter.
     *
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is a letter.
     */
    public boolean isLetter() {
        return isLetter;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is a lower-case character.
     *
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is a lower-case character.
     */
    public boolean isLowerCase() {
        return isLowerCaseChar;
    }
    /**
     * Indicates whether or not the char value associated with this
     * {@code ASCIICharProp} is an upper-case character.
     *
     * @return {@code true} if the char value associated with this
     *         {@code ASCIICharProp} is an upper-case character.
     */
    public boolean isUpperCase() {
        return isUpperCaseChar;
    }
    /**
     * Returns the lower-case char value associated with this
     * {@code ASCIICharProp}.
     *
     * @return The lower-case char value associated with this
     *         {@code ASCIICharProp}.
     */
    public char toLowerCase() {
        return lowerCaseChar;
    }
    @Override
    public String toString() {
        return stringValue;
    }
    /**
     * Returns the upper-case char value associated with this
     * {@code ASCIICharProp}.
     *
     * @return The upper-case char value associated with this
     *         {@code ASCIICharProp}.
     */
    public char toUpperCase() {
        return upperCaseChar;
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java
New file
@@ -0,0 +1,260 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009-2010 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.util;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.forgerock.util.Function;
import org.forgerock.util.promise.NeverThrowsException;
/** Additional {@code Collection} based utility methods. */
public final class Collections2 {
    private static class TransformedCollection<M, N, C extends Collection<M>> extends
            AbstractCollection<N> implements Collection<N> {
        protected final C collection;
        protected final Function<? super M, ? extends N, NeverThrowsException> funcMtoN;
        protected final Function<? super N, ? extends M, NeverThrowsException> funcNtoM;
        protected TransformedCollection(final C collection,
                final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
                final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
            this.collection = collection;
            this.funcMtoN = funcMtoN;
            this.funcNtoM = funcNtoM;
        }
        @Override
        public boolean add(final N e) {
            return collection.add(funcNtoM.apply(e));
        }
        @Override
        public void clear() {
            collection.clear();
        }
        @Override
        @SuppressWarnings("unchecked")
        public boolean contains(final Object o) {
            return collection.contains(funcNtoM.apply((N) o));
        }
        @Override
        public boolean isEmpty() {
            return collection.isEmpty();
        }
        @Override
        public Iterator<N> iterator() {
            return Iterators.transformedIterator(collection.iterator(), funcMtoN);
        }
        @Override
        @SuppressWarnings("unchecked")
        public boolean remove(final Object o) {
            return collection.remove(funcNtoM.apply((N) o));
        }
        @Override
        public int size() {
            return collection.size();
        }
    }
    private static final class TransformedList<M, N> extends
            TransformedCollection<M, N, List<M>> implements List<N> {
        private TransformedList(final List<M> list,
                final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
                final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
            super(list, funcMtoN, funcNtoM);
        }
        @Override
        public void add(final int index, final N element) {
            collection.add(index, funcNtoM.apply(element));
        }
        @Override
        public boolean addAll(final int index, final Collection<? extends N> c) {
            // We cannot transform c here due to type-safety.
            boolean result = false;
            for (final N e : c) {
                result |= add(e);
            }
            return result;
        }
        @Override
        public N get(final int index) {
            return funcMtoN.apply(collection.get(index));
        }
        @Override
        @SuppressWarnings("unchecked")
        public int indexOf(final Object o) {
            return collection.indexOf(funcNtoM.apply((N) o));
        }
        @Override
        @SuppressWarnings("unchecked")
        public int lastIndexOf(final Object o) {
            return collection.lastIndexOf(funcNtoM.apply((N) o));
        }
        @Override
        public ListIterator<N> listIterator() {
            return listIterator(0);
        }
        @Override
        public ListIterator<N> listIterator(final int index) {
            final ListIterator<M> iterator = collection.listIterator(index);
            return new ListIterator<N>() {
                @Override
                public void add(final N e) {
                    iterator.add(funcNtoM.apply(e));
                }
                @Override
                public boolean hasNext() {
                    return iterator.hasNext();
                }
                @Override
                public boolean hasPrevious() {
                    return iterator.hasPrevious();
                }
                @Override
                public N next() {
                    return funcMtoN.apply(iterator.next());
                }
                @Override
                public int nextIndex() {
                    return iterator.nextIndex();
                }
                @Override
                public N previous() {
                    return funcMtoN.apply(iterator.previous());
                }
                @Override
                public int previousIndex() {
                    return iterator.previousIndex();
                }
                @Override
                public void remove() {
                    iterator.remove();
                }
                @Override
                public void set(final N e) {
                    iterator.set(funcNtoM.apply(e));
                }
            };
        }
        @Override
        public N remove(final int index) {
            return funcMtoN.apply(collection.remove(index));
        }
        @Override
        public N set(final int index, final N element) {
            final M result = collection.set(index, funcNtoM.apply(element));
            return funcMtoN.apply(result);
        }
        @Override
        public List<N> subList(final int fromIndex, final int toIndex) {
            final List<M> subList = collection.subList(fromIndex, toIndex);
            return new TransformedList<>(subList, funcMtoN, funcNtoM);
        }
    }
    /**
     * Returns a view of {@code collection} whose values have been mapped to
     * elements of type {@code N} using {@code funcMtoN}. The returned
     * collection supports all operations.
     *
     * @param <M>
     *            The type of elements contained in {@code collection}.
     * @param <N>
     *            The type of elements contained in the returned collection.
     * @param collection
     *            The collection to be transformed.
     * @param funcMtoN
     *            A function which maps values of type {@code M} to values of
     *            type {@code N}. This function will be used when retrieving
     *            values from {@code collection}.
     * @param funcNtoM
     *            A function which maps values of type {@code N} to values of
     *            type {@code M}. This function will be used when performing
     *            queries and adding values to {@code collection} .
     * @return A view of {@code collection} whose values have been mapped to
     *         elements of type {@code N} using {@code funcMtoN}.
     */
    public static <M, N> Collection<N> transformedCollection(final Collection<M> collection,
            final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
            final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
        return new TransformedCollection<>(collection, funcMtoN, funcNtoM);
    }
    /**
     * Returns a view of {@code list} whose values have been mapped to elements
     * of type {@code N} using {@code funcMtoN}. The returned list supports all
     * operations.
     *
     * @param <M>
     *            The type of elements contained in {@code list}.
     * @param <N>
     *            The type of elements contained in the returned list.
     * @param list
     *            The list to be transformed.
     * @param funcMtoN
     *            A function which maps values of type {@code M} to values of
     *            type {@code N}. This function will be used when retrieving
     *            values from {@code list}.
     * @param funcNtoM
     *            A function which maps values of type {@code N} to values of
     *            type {@code M}. This function will be used when performing
     *            queries and adding values to {@code list} .
     * @return A view of {@code list} whose values have been mapped to elements
     *         of type {@code N} using {@code funcMtoN}.
     */
    public static <M, N> List<N> transformedList(final List<M> list,
            final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
            final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
        return new TransformedList<>(list, funcMtoN, funcNtoM);
    }
    /** Prevent instantiation. */
    private Collections2() {
        // Do nothing.
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java
New file
@@ -0,0 +1,325 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009-2010 Sun Microsystems, Inc.
 * Portions copyright 2013-2015 ForgeRock AS.
 */
package com.forgerock.opendj.util;
import java.util.Collection;
import java.util.Iterator;
import org.forgerock.util.Function;
import org.forgerock.util.promise.NeverThrowsException;
/**
 * Utility methods for manipulating {@link Iterable}s.
 */
public final class Iterables {
    private static abstract class AbstractIterable<M> implements Iterable<M> {
        @Override
        public String toString() {
            return Iterables.toString(this);
        }
    }
    private static final class ArrayIterable<M> extends AbstractIterable<M> {
        private final M[] a;
        /** Constructed via factory methods. */
        private ArrayIterable(final M[] a) {
            this.a = a;
        }
        @Override
        public Iterator<M> iterator() {
            return Iterators.arrayIterator(a);
        }
    }
    private static final class EmptyIterable<M> extends AbstractIterable<M> {
        @Override
        public Iterator<M> iterator() {
            return Iterators.emptyIterator();
        }
    }
    private static final class FilteredIterable<M, P> extends AbstractIterable<M> {
        private final Iterable<M> iterable;
        private final P parameter;
        private final Predicate<? super M, P> predicate;
        /** Constructed via factory methods. */
        private FilteredIterable(final Iterable<M> iterable,
                final Predicate<? super M, P> predicate, final P p) {
            this.iterable = iterable;
            this.predicate = predicate;
            this.parameter = p;
        }
        @Override
        public Iterator<M> iterator() {
            return Iterators.filteredIterator(iterable.iterator(), predicate, parameter);
        }
    }
    private static final class SingletonIterable<M> extends AbstractIterable<M> {
        private final M value;
        /** Constructed via factory methods. */
        private SingletonIterable(final M value) {
            this.value = value;
        }
        @Override
        public Iterator<M> iterator() {
            return Iterators.singletonIterator(value);
        }
    }
    private static final class TransformedIterable<M, N> extends AbstractIterable<N> {
        private final Function<? super M, ? extends N, NeverThrowsException> function;
        private final Iterable<M> iterable;
        /** Constructed via factory methods. */
        private TransformedIterable(final Iterable<M> iterable,
                final Function<? super M, ? extends N, NeverThrowsException> function) {
            this.iterable = iterable;
            this.function = function;
        }
        @Override
        public Iterator<N> iterator() {
            return Iterators.transformedIterator(iterable.iterator(), function);
        }
    }
    private static final class UnmodifiableIterable<M> extends AbstractIterable<M> {
        private final Iterable<M> iterable;
        /** Constructed via factory methods. */
        private UnmodifiableIterable(final Iterable<M> iterable) {
            this.iterable = iterable;
        }
        @Override
        public Iterator<M> iterator() {
            return Iterators.unmodifiableIterator(iterable.iterator());
        }
    }
    private static final Iterable<Object> EMPTY_ITERABLE = new EmptyIterable<>();
    /**
     * Returns an iterable containing the elements of {@code a}. The returned
     * iterable's iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of elements contained in {@code a}.
     * @param a
     *            The array of elements.
     * @return An iterable containing the elements of {@code a}.
     */
    public static <M> Iterable<M> arrayIterable(final M[] a) {
        return new ArrayIterable<>(a);
    }
    /**
     * Returns an immutable empty iterable.
     *
     * @param <M>
     *            The required type of the empty iterable.
     * @return An immutable empty iterable.
     */
    @SuppressWarnings("unchecked")
    public static <M> Iterable<M> emptyIterable() {
        return (Iterable<M>) EMPTY_ITERABLE;
    }
    /**
     * Returns a filtered view of {@code iterable} containing only those
     * elements which match {@code predicate}. The returned iterable's iterator
     * supports element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterable}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterable}.
     * @param <P>
     *            The type of the additional parameter to the predicate's
     *            {@code matches} method. Use {@link java.lang.Void} for
     *            predicates that do not need an additional parameter.
     * @param iterable
     *            The iterable to be filtered.
     * @param predicate
     *            The predicate.
     * @param p
     *            A predicate specified parameter.
     * @return A filtered view of {@code iterable} containing only those
     *         elements which match {@code predicate}.
     */
    public static <M, P> Iterable<M> filteredIterable(final Iterable<M> iterable,
            final Predicate<? super M, P> predicate, final P p) {
        return new FilteredIterable<>(iterable, predicate, p);
    }
    /**
     * Returns a filtered view of {@code iterable} containing only those
     * elements which match {@code predicate}. The returned iterable's iterator
     * supports element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterable}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterable}.
     * @param iterable
     *            The iterable to be filtered.
     * @param predicate
     *            The predicate.
     * @return A filtered view of {@code iterable} containing only those
     *         elements which match {@code predicate}.
     */
    public static <M> Iterable<M> filteredIterable(final Iterable<M> iterable,
            final Predicate<? super M, Void> predicate) {
        return new FilteredIterable<>(iterable, predicate, null);
    }
    /**
     * Returns {@code true} if the provided iterable does not contain any
     * elements.
     *
     * @param iterable
     *            The iterable.
     * @return {@code true} if the provided iterable does not contain any
     *         elements.
     */
    public static boolean isEmpty(final Iterable<?> iterable) {
        if (iterable instanceof Collection) {
            // Fall-through if possible and potentially avoid allocation.
            return ((Collection<?>) iterable).isEmpty();
        } else {
            return !iterable.iterator().hasNext();
        }
    }
    /**
     * Returns an iterable containing the single element {@code value}. The
     * returned iterable's iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of the single element {@code value}.
     * @param value
     *            The single element.
     * @return An iterable containing the single element {@code value}.
     */
    public static <M> Iterable<M> singletonIterable(final M value) {
        return new SingletonIterable<>(value);
    }
    /**
     * Returns the number of elements contained in the provided iterable.
     *
     * @param iterable
     *            The iterable.
     * @return The number of elements contained in the provided iterable.
     */
    public static int size(final Iterable<?> iterable) {
        if (iterable instanceof Collection) {
            // Fall-through if possible and potentially benefit from constant time calculation.
            return ((Collection<?>) iterable).size();
        } else {
            final Iterator<?> i = iterable.iterator();
            int sz = 0;
            while (i.hasNext()) {
                i.next();
                sz++;
            }
            return sz;
        }
    }
    /**
     * Returns a string representation of the provided iterable composed of an
     * opening square bracket, followed by each element separated by commas, and
     * then a closing square bracket.
     *
     * @param iterable
     *            The iterable whose string representation is to be returned.
     * @return A string representation of the provided iterable.
     * @see java.util.AbstractCollection#toString()
     */
    public static String toString(final Iterable<?> iterable) {
        if (iterable instanceof Collection) {
            // Fall-through if possible.
            return ((Collection<?>) iterable).toString();
        } else {
            final StringBuilder builder = new StringBuilder();
            boolean firstValue = true;
            builder.append('[');
            for (final Object value : iterable) {
                if (!firstValue) {
                    builder.append(", ");
                }
                builder.append(value);
                firstValue = false;
            }
            builder.append(']');
            return builder.toString();
        }
    }
    /**
     * Returns a view of {@code iterable} whose values have been mapped to
     * elements of type {@code N} using {@code function}. The returned
     * iterable's iterator supports element removal via the {@code remove()}
     * method subject to any constraints imposed by {@code iterable}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterable}.
     * @param <N>
     *            The type of elements contained in the returned iterable.
     * @param iterable
     *            The iterable to be transformed.
     * @param function
     *            The function.
     * @return A view of {@code iterable} whose values have been mapped to
     *         elements of type {@code N} using {@code function}.
     */
    public static <M, N> Iterable<N> transformedIterable(final Iterable<M> iterable,
            final Function<? super M, ? extends N, NeverThrowsException> function) {
        return new TransformedIterable<>(iterable, function);
    }
    /**
     * Returns a read-only view of {@code iterable} whose iterator does not
     * support element removal via the {@code remove()}. Attempts to use the
     * {@code remove()} method will result in a
     * {@code UnsupportedOperationException}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterable}.
     * @param iterable
     *            The iterable to be made read-only.
     * @return A read-only view of {@code iterable} whose iterator does not
     *         support element removal via the {@code remove()}.
     */
    public static <M> Iterable<M> unmodifiableIterable(final Iterable<M> iterable) {
        return new UnmodifiableIterable<>(iterable);
    }
    /** Prevent instantiation. */
    private Iterables() {
        // Do nothing.
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java
New file
@@ -0,0 +1,341 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009-2010 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.forgerock.util.Function;
import org.forgerock.util.promise.NeverThrowsException;
/** Utility methods for manipulating {@link Iterator}s. */
public final class Iterators {
    private static final class ArrayIterator<M> implements Iterator<M> {
        private int i;
        private final M[] a;
        /** Constructed via factory methods. */
        private ArrayIterator(final M[] a) {
            this.a = a;
        }
        @Override
        public boolean hasNext() {
            return i < a.length;
        }
        @Override
        public M next() {
            if (hasNext()) {
                return a[i++];
            } else {
                throw new NoSuchElementException();
            }
        }
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class EmptyIterator<M> implements Iterator<M> {
        @Override
        public boolean hasNext() {
            return false;
        }
        @Override
        public M next() {
            throw new NoSuchElementException();
        }
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class FilteredIterator<M, P> implements Iterator<M> {
        private boolean hasNextMustIterate = true;
        private final Iterator<M> iterator;
        private M next;
        private final P parameter;
        private final Predicate<? super M, P> predicate;
        /** Constructed via factory methods. */
        private FilteredIterator(final Iterator<M> iterator,
                final Predicate<? super M, P> predicate, final P p) {
            this.iterator = iterator;
            this.predicate = predicate;
            this.parameter = p;
        }
        @Override
        public boolean hasNext() {
            if (hasNextMustIterate) {
                hasNextMustIterate = false;
                while (iterator.hasNext()) {
                    next = iterator.next();
                    if (predicate.matches(next, parameter)) {
                        return true;
                    }
                }
                next = null;
                return false;
            } else {
                return next != null;
            }
        }
        @Override
        public M next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            hasNextMustIterate = true;
            return next;
        }
        @Override
        public void remove() {
            iterator.remove();
        }
    }
    private static final class SingletonIterator<M> implements Iterator<M> {
        private M value;
        /** Constructed via factory methods. */
        private SingletonIterator(final M value) {
            this.value = value;
        }
        @Override
        public boolean hasNext() {
            return value != null;
        }
        @Override
        public M next() {
            if (value != null) {
                final M tmp = value;
                value = null;
                return tmp;
            } else {
                throw new NoSuchElementException();
            }
        }
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class TransformedIterator<M, N> implements Iterator<N> {
        private final Function<? super M, ? extends N, NeverThrowsException> function;
        private final Iterator<M> iterator;
        /** Constructed via factory methods. */
        private TransformedIterator(final Iterator<M> iterator,
                final Function<? super M, ? extends N, NeverThrowsException> function) {
            this.iterator = iterator;
            this.function = function;
        }
        @Override
        public boolean hasNext() {
            return iterator.hasNext();
        }
        @Override
        public N next() {
            return function.apply(iterator.next());
        }
        @Override
        public void remove() {
            iterator.remove();
        }
    }
    private static final class UnmodifiableIterator<M> implements Iterator<M> {
        private final Iterator<M> iterator;
        private UnmodifiableIterator(final Iterator<M> iterator) {
            this.iterator = iterator;
        }
        @Override
        public boolean hasNext() {
            return iterator.hasNext();
        }
        @Override
        public M next() {
            return iterator.next();
        }
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final Iterator<Object> EMPTY_ITERATOR = new EmptyIterator<>();
    /**
     * Returns an iterator over the elements contained in {@code a}. The
     * returned iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of elements contained in {@code a}.
     * @param a
     *            The array of elements to be returned by the iterator.
     * @return An iterator over the elements contained in {@code a}.
     */
    public static <M> Iterator<M> arrayIterator(final M[] a) {
        return new ArrayIterator<>(a);
    }
    /**
     * Returns an immutable empty iterator.
     *
     * @param <M>
     *            The required type of the empty iterator.
     * @return An immutable empty iterator.
     */
    @SuppressWarnings("unchecked")
    public static <M> Iterator<M> emptyIterator() {
        return (Iterator<M>) EMPTY_ITERATOR;
    }
    /**
     * Returns a filtered view of {@code iterator} containing only those
     * elements which match {@code predicate}. The returned iterator supports
     * element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param <P>
     *            The type of the additional parameter to the predicate's
     *            {@code matches} method. Use {@link java.lang.Void} for
     *            predicates that do not need an additional parameter.
     * @param iterator
     *            The iterator to be filtered.
     * @param predicate
     *            The predicate.
     * @param p
     *            A predicate specified parameter.
     * @return A filtered view of {@code iterator} containing only those
     *         elements which match {@code predicate}.
     */
    public static <M, P> Iterator<M> filteredIterator(final Iterator<M> iterator,
            final Predicate<? super M, P> predicate, final P p) {
        return new FilteredIterator<>(iterator, predicate, p);
    }
    /**
     * Returns a filtered view of {@code iterator} containing only those
     * elements which match {@code predicate}. The returned iterator supports
     * element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param iterator
     *            The iterator to be filtered.
     * @param predicate
     *            The predicate.
     * @return A filtered view of {@code iterator} containing only those
     *         elements which match {@code predicate}.
     */
    public static <M> Iterator<M> filteredIterator(final Iterator<M> iterator,
            final Predicate<? super M, Void> predicate) {
        return new FilteredIterator<>(iterator, predicate, null);
    }
    /**
     * Returns an iterator containing the single element {@code value}. The
     * returned iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of the single element {@code value}.
     * @param value
     *            The single element to be returned by the iterator.
     * @return An iterator containing the single element {@code value}.
     */
    public static <M> Iterator<M> singletonIterator(final M value) {
        return new SingletonIterator<>(value);
    }
    /**
     * Returns a view of {@code iterator} whose values have been mapped to
     * elements of type {@code N} using {@code function}. The returned iterator
     * supports element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param <N>
     *            The type of elements contained in the returned iterator.
     * @param iterator
     *            The iterator to be transformed.
     * @param function
     *            The function.
     * @return A view of {@code iterator} whose values have been mapped to
     *         elements of type {@code N} using {@code function}.
     */
    public static <M, N> Iterator<N> transformedIterator(final Iterator<M> iterator,
            final Function<? super M, ? extends N, NeverThrowsException> function) {
        return new TransformedIterator<>(iterator, function);
    }
    /**
     * Returns a read-only view of {@code iterator} which does not support
     * element removal via the {@code remove()}. Attempts to use the
     * {@code remove()} method will result in a
     * {@code UnsupportedOperationException}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param iterator
     *            The iterator to be made read-only.
     * @return A read-only view of {@code iterator} which does not support
     *         element removal via the {@code remove()}.
     */
    public static <M> Iterator<M> unmodifiableIterator(final Iterator<M> iterator) {
        return new UnmodifiableIterator<>(iterator);
    }
    /** Prevent instantiation. */
    private Iterators() {
        // Do nothing.
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/OperatingSystem.java
New file
@@ -0,0 +1,247 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 */
package com.forgerock.opendj.util;
/**
 * This class defines an enumeration that may be used to identify the operating system
 * on which the JVM is running.
 */
public enum OperatingSystem {
    /**
     * The value indicating the AIX operating system.
     */
    AIX("AIX", false, false, true),
    /**
     * The value indicating the FreeBSD operating system.
     */
    FREEBSD("FreeBSD", false, false, true),
    /**
     * The value indicating the HP-UX operating system.
     */
    HPUX("HP UX", false, false, true),
    /**
     * The value indicating the Linux operating system.
     */
    LINUX("Linux", false, false, true),
    /**
     * The value indicating the Mac OS X operating system.
     */
    MACOSX("Mac OS X", false, true, true),
    /**
     * The value indicating the Solaris operating system.
     */
    SOLARIS("Solaris", false, false, true),
    /**
     * The value indicating the Windows operating system.
     */
    WINDOWS("Windows", true, false, false),
    /**
     * The value indicating the Windows 7 operating system.
     */
    WINDOWS7("Windows 7", true, false, false),
    /**
     * The value indicating the Windows Vista operating system.
     */
    WINDOWS_VISTA("Windows Vista", true, false, false),
    /**
     * The value indicating the Windows Server 2008 operating system.
     */
    WINDOWS_SERVER_2008("Server 2008", true, false, false),
    /**
     * The value indicating the z/OS operating system.
     */
    ZOS("z/OS", false, false, false),
    /**
     * The value indicating an unknown operating system.
     */
    UNKNOWN("Unknown", false, false, false);
    /** The human-readable name for this operating system. */
    private String osName;
    private boolean isWindows;
    private boolean isMacOS;
    private boolean isUnixBased;
    private static final OperatingSystem INSTANCE = forName(System.getProperty("os.name"));
    /**
     * Creates a new operating system value with the provided name.
     *
     * @param osName
     *            The human-readable name for the operating system.
     */
    private OperatingSystem(String osName, boolean isWindows, boolean isMacOS, boolean isUnixBased) {
        this.osName = osName;
        this.isWindows = isWindows;
        this.isMacOS = isMacOS;
        this.isUnixBased = isUnixBased;
    }
    /**
     * Retrieves the human-readable name of this operating system.
     *
     * @return The human-readable name for this operating system.
     */
    @Override
    public String toString() {
        return osName;
    }
    /**
     * Retrieves the operating system for the provided name.
     *
     * @param osName
     *            The name for which to retrieve the corresponding operating system.
     * @return The operating system for the provided name.
     */
    public static OperatingSystem forName(final String osName) {
        if (osName == null) {
            return UNKNOWN;
        }
        final String lowerName = osName.toLowerCase();
        if (lowerName.contains("solaris") || lowerName.contains("sunos")) {
            return SOLARIS;
        } else if (lowerName.contains("linux")) {
            return LINUX;
        } else if (lowerName.contains("hp-ux")
                || lowerName.contains("hp ux")
                || lowerName.contains("hpux")) {
            return HPUX;
        } else if (lowerName.contains("aix")) {
            return AIX;
        } else if (lowerName.contains("windows")) {
            if (lowerName.indexOf("windows 7") != -1) {
                return WINDOWS7;
            } else if (lowerName.indexOf("vista") != -1) {
                return WINDOWS_VISTA;
            } else if (lowerName.indexOf("server 2008") != -1) {
                return WINDOWS_SERVER_2008;
            }
            return WINDOWS;
        } else if (lowerName.contains("freebsd") || lowerName.contains("free bsd")) {
            return FREEBSD;
        } else if (lowerName.contains("macos x") || lowerName.contains("mac os x")) {
            return MACOSX;
        } else if (lowerName.contains("z/os")) {
            return ZOS;
        }
        return UNKNOWN;
    }
    /**
     * Returns the operating system on which the JVM is running.
     *
     * @return The operating system on which the JVM is running
     */
    public static OperatingSystem getOperatingSystem() {
        return INSTANCE;
    }
    /**
     * Indicates whether the underlying operating system is a Windows variant.
     *
     * @return {@code true} if the underlying operating system is a Windows variant, or {@code false} if not.
     */
    public static boolean isWindows() {
        return INSTANCE.isWindows;
    }
    /**
     * Indicates whether the underlying operating system is Windows Vista.
     *
     * @return {@code true} if the underlying operating system is Windows Vista, or {@code false} if not.
     */
    public static boolean isVista() {
        return INSTANCE == WINDOWS_VISTA;
    }
    /**
     * Indicates whether the underlying operating system is Windows 2008.
     *
     * @return {@code true} if the underlying operating system is Windows 2008, or {@code false} if not.
     */
    public static boolean isWindows2008() {
        return INSTANCE == WINDOWS_SERVER_2008;
    }
    /**
     * Indicates whether the underlying operating system is Windows 7.
     *
     * @return {@code true} if the underlying operating system is Windows 7, or {@code false} if not.
     */
    public static boolean isWindows7() {
        return INSTANCE == WINDOWS7;
    }
    /**
     * Returns {@code true} if we are running under Mac OS and {@code false} otherwise.
     *
     * @return {@code true} if we are running under Mac OS and {@code false} otherwise.
     */
    public static boolean isMacOS() {
        return INSTANCE.isMacOS;
    }
    /**
     * Returns {@code true} if we are running under Unix and {@code false} otherwise.
     *
     * @return {@code true} if we are running under Unix and {@code false} otherwise.
     */
    public static boolean isUnix() {
        return INSTANCE.isUnixBased;
    }
    /**
     * Returns {@code true} if the OS is Unix based.
     *
     * @return {@code true} if the OS is Unix based.
     */
    public static boolean isUnixBased() {
        return INSTANCE.isUnixBased;
    }
    /**
     * Returns {@code true} if the OS is Unknown.
     *
     * @return {@code true} if the OS is Unknown.
     */
    public static boolean isUnknown() {
        return INSTANCE == UNKNOWN;
    }
    /**
     * Indicates whether the underlying operating system has UAC (User Access Control).
     *
     * @return {@code true} if the underlying operating system has UAC (User Access Control), or {@code false} if not.
     */
    public static boolean hasUAC() {
        return isVista() || isWindows2008() || isWindows7();
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/PackedLong.java
New file
@@ -0,0 +1,235 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2015 ForgeRock AS.
 */
package com.forgerock.opendj.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/**
 * Provides static methods to manipulate compact long representation. Compact long allow to stores unsigned long values
 * up to 56 bits using a variable number of bytes from 1 to 8. The binary representations of this compact encoding has
 * the interesting properties of maintaining correct order of values when compared.
 */
public final class PackedLong {
    /** Maximum size in bytes of a compact encoded value. */
    public static final int MAX_COMPACT_SIZE = 8;
    private PackedLong() {
    }
    private static final int[] DECODE_SIZE = new int[256];
    static {
        Arrays.fill(DECODE_SIZE, 0, 0x80, 1);
        Arrays.fill(DECODE_SIZE, 0x80, 0xc0, 2);
        Arrays.fill(DECODE_SIZE, 0xc0, 0xe0, 3);
        Arrays.fill(DECODE_SIZE, 0xe0, 0xf0, 4);
        Arrays.fill(DECODE_SIZE, 0xf0, 0xf8, 5);
        Arrays.fill(DECODE_SIZE, 0xf8, 0xfc, 6);
        Arrays.fill(DECODE_SIZE, 0xfc, 0xfe, 7);
        Arrays.fill(DECODE_SIZE, 0xfe, 0x100, 8);
    }
    /** Maximum value that can be stored with a compacted representation. */
    public static final long COMPACTED_MAX_VALUE = 0x00FFFFFFFFFFFFFFL;
    /**
     * Append the compact representation of the value into the {@link OutputStream}.
     *
     * @param os
     *            {@link OutputStream} where the compact representation will be written.
     * @param value
     *            Value to be encoded and written in the compact long format.
     * @throws IOException
     *             if problem appear in the underlying {@link OutputStream}
     * @return Number of bytes which has been written in the buffer.
     */
    public static int writeCompactUnsigned(OutputStream os, long value) throws IOException {
        final int size = getEncodedSize(value);
        switch (size) {
        case 1:
            os.write((int) value);
            break;
        case 2:
            os.write((int) ((value >>> 8) | 0x80L));
            os.write((int) value);
            break;
        case 3:
            os.write((int) ((value >>> 16) | 0xc0L));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        case 4:
            os.write((int) ((value >>> 24) | 0xe0L));
            os.write((int) (value >>> 16));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        case 5:
            os.write((int) ((value >>> 32) | 0xf0L));
            os.write((int) (value >>> 24));
            os.write((int) (value >>> 16));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        case 6:
            os.write((int) ((value >>> 40) | 0xf8L));
            os.write((int) (value >>> 32));
            os.write((int) (value >>> 24));
            os.write((int) (value >>> 16));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        case 7:
            os.write((int) ((value >>> 48) | 0xfcL));
            os.write((int) (value >>> 40));
            os.write((int) (value >>> 32));
            os.write((int) (value >>> 24));
            os.write((int) (value >>> 16));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        case 8:
            os.write(0xfe);
            os.write((int) (value >>> 48));
            os.write((int) (value >>> 40));
            os.write((int) (value >>> 32));
            os.write((int) (value >>> 24));
            os.write((int) (value >>> 16));
            os.write((int) (value >>> 8));
            os.write((int) (value));
            break;
        default:
            throw new IllegalArgumentException();
        }
        return size;
    }
    /**
     * Get the number of bytes required to store the given value using the compact long representation.
     *
     * @param value
     *            Value to get the compact representation's size.
     * @return Number of bytes required to store the compact long representation of the value.
     */
    public static int getEncodedSize(long value) {
        if (value < 0x80L) {
            return 1;
        } else if (value < 0x4000L) {
            return 2;
        } else if (value < 0x200000L) {
            return 3;
        } else if (value < 0x10000000L) {
            return 4;
        } else if (value < 0x800000000L) {
            return 5;
        } else if (value < 0x40000000000L) {
            return 6;
        } else if (value < 0x2000000000000L) {
            return 7;
        } else if (value < 0x100000000000000L) {
            return 8;
        } else {
            throw new IllegalArgumentException("value out of range: " + value);
        }
    }
    /**
     * Decode and get the value of the compact long contained in the specified {@link InputStream}.
     *
     * @param is
     *            Stream where to read the compact unsigned long
     * @return The long value.
     * @throws IOException
     *             If the first byte cannot be read for any reason other than the end of the file, if the input stream
     *             has been closed, or if some other I/O error occurs.
     */
    public static long readCompactUnsignedLong(InputStream is) throws IOException {
        final int b0 = checkNotEndOfStream(is.read());
        final int size = decodeSize(b0);
        long value;
        switch (size) {
        case 1:
            value = b2l((byte) b0);
            break;
        case 2:
            value = (b0 & 0x3fL) << 8;
            value |= checkNotEndOfStream(is.read());
            break;
        case 3:
            value = (b0 & 0x1fL) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= checkNotEndOfStream(is.read());
            break;
        case 4:
            value = (b0 & 0x0fL) << 24;
            value |= ((long) checkNotEndOfStream(is.read())) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= is.read();
            break;
        case 5:
            value = (b0 & 0x07L) << 32;
            value |= ((long) checkNotEndOfStream(is.read())) << 24;
            value |= ((long) checkNotEndOfStream(is.read())) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= (is.read());
            break;
        case 6:
            value = (b0 & 0x03L) << 40;
            value |= ((long) checkNotEndOfStream(is.read())) << 32;
            value |= ((long) checkNotEndOfStream(is.read())) << 24;
            value |= ((long) checkNotEndOfStream(is.read())) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= is.read();
            break;
        case 7:
            value = (b0 & 0x01L) << 48;
            value |= ((long) checkNotEndOfStream(is.read())) << 40;
            value |= ((long) checkNotEndOfStream(is.read())) << 32;
            value |= ((long) checkNotEndOfStream(is.read())) << 24;
            value |= ((long) checkNotEndOfStream(is.read())) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= is.read();
            break;
        default:
            value = ((long) checkNotEndOfStream(is.read())) << 48;
            value |= ((long) checkNotEndOfStream(is.read())) << 40;
            value |= ((long) checkNotEndOfStream(is.read())) << 32;
            value |= ((long) checkNotEndOfStream(is.read())) << 24;
            value |= ((long) checkNotEndOfStream(is.read())) << 16;
            value |= ((long) checkNotEndOfStream(is.read())) << 8;
            value |= is.read();
        }
        return value;
    }
    private static int checkNotEndOfStream(final int byteValue) {
        if (byteValue == -1) {
            throw new IllegalArgumentException("End of stream reached.");
        }
        return byteValue;
    }
    private static int decodeSize(int b) {
        return DECODE_SIZE[b & 0xff];
    }
    private static long b2l(final byte b) {
        return b & 0xffL;
    }
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/Predicate.java
New file
@@ -0,0 +1,43 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2009 Sun Microsystems, Inc.
 */
package com.forgerock.opendj.util;
/**
 * Predicates transform input values of type {@code M} to a boolean output value
 * and are typically used for performing filtering.
 *
 * @param <M>
 *            The type of input values matched by this predicate.
 * @param <P>
 *            The type of the additional parameter to this predicate's
 *            {@code matches} method. Use {@link java.lang.Void} for predicates
 *            that do not need an additional parameter.
 */
public interface Predicate<M, P> {
    /**
     * Indicates whether or not this predicate matches the provided input value
     * of type {@code M}.
     *
     * @param value
     *            The input value for which to make the determination.
     * @param p
     *            A predicate specified parameter.
     * @return {@code true} if this predicate matches {@code value}, otherwise
     *         {@code false}.
     */
    boolean matches(M value, P p);
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/ReferenceCountedObject.java
New file
@@ -0,0 +1,156 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2013 ForgeRock AS.
 */
package com.forgerock.opendj.util;
/**
 * An object which is lazily created when first referenced, and destroyed when
 * the last reference is released.
 *
 * @param <T>
 *            The type of referenced object.
 */
public abstract class ReferenceCountedObject<T> {
    /**
     * A reference to the reference counted object which will automatically be
     * released during garbage collection.
     */
    public final class Reference {
        /**
         * The value will be accessed by the finalizer thread so it needs to be
         * volatile in order to ensure that updates are published.
         */
        private volatile T value;
        private Reference(final T value) {
            this.value = value;
        }
        /**
         * Returns the referenced object.
         *
         * @return The referenced object.
         * @throws NullPointerException
         *             If the referenced object has already been released.
         */
        public T get() {
            if (value == null) {
                throw new NullPointerException(); // Fail-fast.
            }
            return value;
        }
        /**
         * Decrements the reference count for the reference counted object if
         * this reference refers to the reference counted instance. If the
         * reference count drops to zero then the referenced object will be
         * destroyed.
         */
        public void release() {
            T instanceToRelease = null;
            synchronized (lock) {
                if (value != null) {
                    if (instance == value && --refCount == 0) {
                        // This was the last reference.
                        instanceToRelease = value;
                        instance = null;
                    }
                    /*
                     * Force NPE for subsequent get() attempts and prevent
                     * multiple releases.
                     */
                    value = null;
                }
            }
            if (instanceToRelease != null) {
                destroyInstance(instanceToRelease);
            }
        }
        /**
         * Provide a finalizer because reference counting is intended for
         * expensive rarely created resources which should not be accidentally
         * left around.
         */
        @Override
        protected void finalize() {
            release();
        }
    }
    private T instance;
    private final Object lock = new Object();
    private int refCount;
    /**
     * Creates a new referenced object whose reference count is initially zero.
     */
    protected ReferenceCountedObject() {
        // Nothing to do.
    }
    /**
     * Returns a reference to the reference counted object.
     *
     * @return A reference to the reference counted object.
     */
    public final Reference acquire() {
        synchronized (lock) {
            if (refCount++ == 0) {
                assert instance == null;
                instance = newInstance();
            }
            assert instance != null;
            return new Reference(instance);
        }
    }
    /**
     * Returns a reference to the provided object or, if it is {@code null}, a
     * reference to the reference counted object.
     *
     * @param value
     *            The object to be referenced, or {@code null} if the reference
     *            counted object should be used.
     * @return A reference to the provided object or, if it is {@code null}, a
     *         reference to the reference counted object.
     */
    public final Reference acquireIfNull(final T value) {
        return value != null ? new Reference(value) : acquire();
    }
    /**
     * Invoked when a reference is released and the reference count will become
     * zero. Implementations should release any resources associated with the
     * resource and should not return until the resources have been released.
     *
     * @param instance
     *            The instance to be destroyed.
     */
    protected abstract void destroyInstance(T instance);
    /**
     * Invoked when a reference is acquired and the current reference count is
     * zero. Implementations should create a new instance as fast as possible.
     *
     * @return The new instance.
     */
    protected abstract T newInstance();
}
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/SizeLimitInputStream.java
New file
@@ -0,0 +1,136 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2009 Sun Microsystems, Inc.
 * Portions Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.util;
import java.io.IOException;
import java.io.InputStream;
/** An implementation of input stream that enforces an read size limit. */
public class SizeLimitInputStream extends InputStream {
    private int bytesRead;
    private int markBytesRead;
    private final int readLimit;
    private final InputStream parentStream;
    /**
     * Creates a new a new size limit input stream.
     *
     * @param parentStream
     *            The parent stream.
     * @param readLimit
     *            The size limit.
     */
    public SizeLimitInputStream(final InputStream parentStream, final int readLimit) {
        this.parentStream = parentStream;
        this.readLimit = readLimit;
    }
    @Override
    public int available() throws IOException {
        final int streamAvail = parentStream.available();
        final int limitedAvail = readLimit - bytesRead;
        return limitedAvail < streamAvail ? limitedAvail : streamAvail;
    }
    @Override
    public void close() throws IOException {
        parentStream.close();
    }
    /**
     * Retrieves the number of bytes read from this stream.
     *
     * @return The number of bytes read from this stream.
     */
    public int getBytesRead() {
        return bytesRead;
    }
    /**
     * Retrieves the size limit of this stream.
     *
     * @return The size limit of this stream.
     */
    public int getSizeLimit() {
        return readLimit;
    }
    @Override
    public synchronized void mark(final int readlimit) {
        parentStream.mark(readlimit);
        markBytesRead = bytesRead;
    }
    @Override
    public boolean markSupported() {
        return parentStream.markSupported();
    }
    @Override
    public int read() throws IOException {
        if (bytesRead >= readLimit) {
            return -1;
        }
        final int b = parentStream.read();
        if (b != -1) {
            ++bytesRead;
        }
        return b;
    }
    @Override
    public int read(final byte[] b, final int off, int len) throws IOException {
        if (off < 0 || len < 0 || off + len > b.length) {
            throw new IndexOutOfBoundsException();
        }
        if (len == 0) {
            return 0;
        }
        if (bytesRead >= readLimit) {
            return -1;
        }
        if (bytesRead + len > readLimit) {
            len = readLimit - bytesRead;
        }
        final int readLen = parentStream.read(b, off, len);
        if (readLen > 0) {
            bytesRead += readLen;
        }
        return readLen;
    }
    @Override
    public synchronized void reset() throws IOException {
        parentStream.reset();
        bytesRead = markBytesRead;
    }
    @Override
    public long skip(long n) throws IOException {
        if (bytesRead + n > readLimit) {
            n = readLimit - bytesRead;
        }
        bytesRead += n;
        return parentStream.skip(n);
    }
}
Diff truncated after the above file
opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/StaticUtils.java opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/SubstringReader.java opendj-sdk/opendj-core/src/main/java/com/forgerock/opendj/util/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1ByteSequenceReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1InputStreamReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1OutputStreamWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1Reader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/ASN1Writer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractASN1Reader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractASN1Writer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/AbstractLDAPMessageHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAP.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPMessageHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/LDAPWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/io/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractAttribute.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractConnectionWrapper.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractEntry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractFilterVisitor.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractMapEntry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractSynchronousConnection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Assertion.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AssertionFailureException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Attribute.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeDescription.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Attributes.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AuthenticationException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AuthorizationException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Base64.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequenceReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CachedConnectionPool.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CancelledResultException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/CommonLDAPOptions.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConditionResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionEventListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionLoadBalancer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConnectionSecurityLayer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ConstraintViolationException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DecodeException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DecodeOptions.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DereferenceAliasesPolicy.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/EntryFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/EntryNotFoundException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Filter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FilterVisitor.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/GSERParser.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/InternalConnection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/KeyManagers.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPClientContext.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LDAPUrl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapPromise.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LdapResultHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LinkedAttribute.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LinkedHashMapEntry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Matcher.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Modification.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ModificationType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/MultipleEntriesFoundException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ReferralException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestContext.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RequestLoadBalancer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SSLContextBuilder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SchemaResolver.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchResultReferenceIOException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SearchScope.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ServerConnection.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ServerConnectionFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/SortKey.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutChecker.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutEventListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TimeoutResultException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TreeMapEntry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/TrustManagers.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ADNotificationRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AssertionRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/AuthorizationIdentityResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/Control.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ControlDecoder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/EntryChangeNotificationResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/GenericControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/GetEffectiveRightsRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ManageDsaITRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/MatchedValuesRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiredResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordExpiringResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyErrorType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyWarningType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PermissiveModifyRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchChangeType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PersistentSearchRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PostReadRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PostReadResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PreReadRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PreReadResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV1RequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ProxiedAuthV2RequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/ServerSideSortResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SimplePagedResultsControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/SubtreeDeleteRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewRequestControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/VirtualListViewResponseControl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbandonRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractSASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AbstractUnmodifiableSASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AddRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AddRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindClient.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindClientImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/BindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/CompareRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DeleteRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExtendedRequestDecoder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/ModifyRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/Request.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/Requests.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindClientImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SASLBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SearchRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnbindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAbandonRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAddRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableAnonymousSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCRAMMD5SASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCancelExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableCompareRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDeleteRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableDigestMD5SASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableExternalSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGSSAPISASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableGenericExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyDNRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableModifyRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePasswordModifyExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiablePlainSASLBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSearchRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableSimpleBindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableStartTLSExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableUnbindRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/UnmodifiableWhoAmIExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequest.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequestImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/requests/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractIntermediateResponse.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResponseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableIntermediateResponseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResponseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/AbstractUnmodifiableResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/BindResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/BindResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/CompareResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/CompareResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ExtendedResultDecoder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponse.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/GenericIntermediateResponseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/IntermediateResponse.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/PasswordModifyExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Response.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Responses.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/Result.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/ResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntry.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultEntryImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReference.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/SearchResultReferenceImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableBindResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableCompareResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableGenericIntermediateResponseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiablePasswordModifyExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultEntryImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableSearchResultReferenceImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/UnmodifiableWhoAmIExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResult.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/WhoAmIExtendedResultImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/responses/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractApproximateMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeUsage.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordExactEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AuthPasswordSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BinarySyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/BooleanSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactAssertionSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateListSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificatePairSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ConflictingSchemaElementException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchema.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaSupportedLocales.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRuleSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DelayedSchema.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DeliveryMethodSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DistinguishedNameSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnhancedGuideSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumOrderingMatchingRule.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/FacsimileNumberSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/FaxSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GenerateCoreSchema.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/GuideSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxDescriptionSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameAndOptionalUIDSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameFormSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OIDSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClassType.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OctetStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PostalAddressSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PrintableStringSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/RegexSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaConstants.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaOptions.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaValidationPolicy.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SubstringAssertionSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SupportedAlgorithmSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSubstringMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TeletexTerminalIdentifierSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TelexNumberSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/TimeBasedMatchingRulesImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDOrderingMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UnknownSchemaElementException.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordExactEqualityMatchingRuleImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UserPasswordSyntaxImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/BindResultLdapPromiseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ConnectionState.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ExtendedResultLdapPromiseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexQueryFactory.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/Indexer.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexingOptions.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromiseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromiseWrapper.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/LdapPromises.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/ResultLdapPromiseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/SearchResultLdapPromiseImpl.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFStream.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecord.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitor.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordVisitorWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ChangeRecordWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionChangeRecordWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryGenerator.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/EntryWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFEntryReader.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIFEntryWriter.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/RejectedChangeRecordListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/RejectedLDIFListener.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateFile.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/package-info.java opendj-sdk/opendj-core/src/main/javadoc/overview.html opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_de.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_es.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_fr.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_ja.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_ko.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_zh_CN.properties opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core_zh_TW.properties opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/addrate.template opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/cities opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/example.template opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/first.names opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/last.names opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/people_and_groups.template opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/states opendj-sdk/opendj-core/src/main/resources/org/forgerock/opendj/ldif/streets opendj-sdk/opendj-core/src/site/xdoc/index.xml.vm opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityRequestControlTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/ldap/controls/AccountUsabilityResponseControlTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/ASCIICharPropTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/OperatingSystemTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/ReferenceCountedObjectTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/StaticUtilsTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/StringPrepProfileTestCase.java opendj-sdk/opendj-core/src/test/java/com/forgerock/opendj/util/UtilTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1ByteSequenceReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1InputStreamReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1OutputStreamWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1ReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/ASN1WriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/io/LDAPReaderWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeDescriptionTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeParserTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributesTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteSequenceReaderTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringBuilderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/CompactDnTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConditionResultTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConnectionPoolTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ConnectionsTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DataProviderIterator.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/EntriesTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/EntryTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/GSERParserTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/GeneralizedTimeTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactoryTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPUrlTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LinkedAttributeTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/LoadBalancerTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/MockScheduler.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ModificationTypeTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/PackedLongTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RequestLoadBalancerTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/ResultCodeTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/SdkTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/SearchScopeTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/TestCaseUtilsTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/controls/ControlsTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AbandonRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AddRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/AnonymousSASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/BindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CancelExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/CompareRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/DeleteRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GenericBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/GenericExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ModifyDNRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/ModifyRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/PasswordModifyExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/RequestsTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/SearchRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/SimpleBindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/StartTLSExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/UnbindRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/requests/WhoAmIExtendedRequestTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/responses/ResponsesTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaElementTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImplTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ApproximateMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeBuilderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AuthPasswordSyntaxImplTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BooleanEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BooleanSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImplTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CertificateSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CoreSchemaTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITStructureRuleTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DistinguishedNameEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EntrySchemaCheckingTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IntegerSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseBuilderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NameFormTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ObjectClassBuilderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/PartialDateAndTimeMatchingRuleTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RelativeTimeGreaterThanMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RelativeTimeLessThanMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaCompatTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaOptionsTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaUtilsTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstringMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelephoneNumberSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDOrderingMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UniqueMemberEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UserPasswordExactEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/WordEqualityMatchingRuleTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicLDAPConnectionFactory.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicLDAPListener.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/BasicTransportProvider.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/ConnectionStateTest.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/spi/LDAPTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionChangeRecordWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionEntryReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/ConnectionEntryWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/EntryGeneratorTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryReaderTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestcase.java opendj-sdk/opendj-core/src/test/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider opendj-sdk/opendj-doc-maven-plugin/pom.xml opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/CommandLineTool.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateGlobalAcisTableMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateRefEntriesMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/package-info.java opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/duration-syntax.html opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/opendj-config.css opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/opendj_logo_sm.png opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/pageaction.gif opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/tab_deselected.jpg opendj-sdk/opendj-doc-maven-plugin/src/main/resources/config-ref/tab_selected.gif opendj-sdk/opendj-doc-maven-plugin/src/main/resources/org/forgerock/opendj/maven/doc/docs.properties opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/log-message-reference.ftl opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/sec-locales-subtypes.ftl opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/table-global-acis.ftl opendj-sdk/opendj-grizzly/pom.xml opendj-sdk/opendj-grizzly/src/main/java/com/forgerock/opendj/grizzly/GrizzlyTransportProvider.java opendj-sdk/opendj-grizzly/src/main/java/com/forgerock/opendj/grizzly/package-info.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferReader.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferWriter.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ConnectionSecurityLayerFilter.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransport.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnection.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionFactory.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListener.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyUtils.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPBaseFilter.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPClientFilter.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPServerFilter.java opendj-sdk/opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/package-info.java opendj-sdk/opendj-grizzly/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider opendj-sdk/opendj-grizzly/src/main/resources/com/forgerock/opendj/grizzly/grizzly.properties opendj-sdk/opendj-grizzly/src/site/xdoc/index.xml.vm opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ASN1BufferReaderTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ASN1BufferWriterTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionFactoryTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPConnectionTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPReaderWriterTestCase.java opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyUtilsTestCase.java opendj-sdk/opendj-ldap-sdk-examples/pom.xml opendj-sdk/opendj-ldap-sdk-examples/src/main/assembly/examples.xml opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Controls.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ExtendedOperations.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetInfo.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ParseAttributes.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuth.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroup.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/package-info.java opendj-sdk/opendj-ldap-sdk-examples/src/main/javadoc/overview.html opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm opendj-sdk/opendj-ldap-sdk-examples/src/test/bin/checkRewriterProxy.sh opendj-sdk/opendj-ldap-toolkit/README opendj-sdk/opendj-ldap-toolkit/legal-notices/THIRDPARTYREADME.txt opendj-sdk/opendj-ldap-toolkit/pom.xml opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/addrate.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/authrate.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapcompare.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapmodify.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldappasswordmodify.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldapsearch.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifdiff.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifmodify.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/ldifsearch.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/makeldif.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/modrate.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bat/searchrate.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/addrate opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/authrate opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapcompare opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapmodify opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldappasswordmodify opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldapsearch opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifdiff opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifmodify opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/ldifsearch opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/makeldif opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/modrate opendj-sdk/opendj-ldap-toolkit/src/main/assembly/bin/searchrate opendj-sdk/opendj-ldap-toolkit/src/main/assembly/descriptor.xml opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/_client-script.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/_script-util.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbat/setcp.bat opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbin/_client-script.sh opendj-sdk/opendj-ldap-toolkit/src/main/assembly/libbin/_script-util.sh opendj-sdk/opendj-ldap-toolkit/src/main/assembly/man-pages.xml opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/DataSource.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFDiff.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFModify.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFSearch.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/MakeLDIF.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunnerOptions.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/StatsThread.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/Utils.java opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/package-info.java opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ca_ES.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_de.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_es.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_fr.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ja.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_ko.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_pl.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_zh_CN.properties opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools_zh_TW.properties opendj-sdk/opendj-ldap-toolkit/src/site/xdoc/index.xml.vm opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AddRateITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/MakeLDIFITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsITCase.java opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestCase.java opendj-sdk/opendj-ldap-toolkit/src/test/resources/dummy-truststore opendj-sdk/opendj-ldap-toolkit/src/test/resources/expected_output.ldif opendj-sdk/opendj-ldap-toolkit/src/test/resources/expected_output_80_column.ldif opendj-sdk/opendj-ldap-toolkit/src/test/resources/invalid_test_template.ldif opendj-sdk/opendj-ldap-toolkit/src/test/resources/valid_test_template.ldif opendj-sdk/opendj-rest2ldap/README opendj-sdk/opendj-rest2ldap/pom.xml opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractLDAPAttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthenticatedConnectionContext.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthorizationPolicy.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AuthzIdTemplate.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/FilterType.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/HttpAuthenticationFilter.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/NameStrategy.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReadOnUpdatePolicy.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/RequestState.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAPHttpApplication.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/WritabilityPolicy.java opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/package-info.java opendj-sdk/opendj-rest2ldap/src/main/resources/META-INF/services/org.forgerock.http.HttpApplication opendj-sdk/opendj-rest2ldap/src/site/xdoc/index.xml.vm opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/AuthzIdTemplateTest.java opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java opendj-sdk/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/TestUtils.java opendj-sdk/opendj-sdk-bom/pom.xml