001/* 002 * Copyright 2017-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2017-2018 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.util.args; 022 023 024 025import java.util.List; 026 027import com.unboundid.util.NotMutable; 028import com.unboundid.util.OID; 029import com.unboundid.util.ThreadSafety; 030import com.unboundid.util.ThreadSafetyLevel; 031 032import static com.unboundid.util.args.ArgsMessages.*; 033 034 035 036/** 037 * This class provides an implementation of an argument value validator that 038 * ensures that values can be parsed as valid object identifiers. 039 */ 040@NotMutable() 041@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 042public final class OIDArgumentValueValidator 043 extends ArgumentValueValidator 044{ 045 // Indicates whether to perform strict validation. 046 private final boolean isStrict; 047 048 049 050 /** 051 * Creates a new OID address argument value validator that will only accept 052 * strictly valid numeric OIDs. 053 */ 054 public OIDArgumentValueValidator() 055 { 056 this(true); 057 } 058 059 060 061 /** 062 * Creates a new OID address argument value validator that will only accept 063 * valid numeric OIDs. 064 * 065 * @param isStrict Indicates whether to perform strict validation. If this 066 * is {@code false}, then the validator will only sure that 067 * each value is a dotted list of digits that does not start 068 * or end with a period and does not contain two consecutive 069 * periods. If this is {@code true}, then it will also 070 * ensure that it contains at least two components, that the 071 * value of the first component is not greater than two, 072 * and that the value of the second component is not greater 073 * than 39 if the value of the first component is zero or 074 * one. 075 */ 076 public OIDArgumentValueValidator(final boolean isStrict) 077 { 078 this.isStrict = isStrict; 079 } 080 081 082 083 /** 084 * Indicates whether this validator is configured to operate in strict mode. 085 * If it not operating in strict mode, then it will only ensure that each 086 * value is is a dotted list of digits that does not start or end with a 087 * period and does not contain two consecutive periods. If it is strict, then 088 * it will also ensure that it contains at least two components, that the 089 * value of the first component is not greater than two, and that the value of 090 * the second component is not greater than 39 if the value of the first 091 * component is zero or one. 092 * 093 * @return {@code true} if this validator is configured to operate in strict 094 * mode, or {@code false} if not. 095 */ 096 public boolean isStrict() 097 { 098 return isStrict; 099 } 100 101 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override() 107 public void validateArgumentValue(final Argument argument, 108 final String valueString) 109 throws ArgumentException 110 { 111 if (valueString.isEmpty()) 112 { 113 throw new ArgumentException(ERR_OID_VALIDATOR_EMPTY.get(valueString, 114 argument.getIdentifierString())); 115 } 116 117 if (valueString.startsWith(".") || valueString.endsWith(".")) 118 { 119 throw new ArgumentException( 120 ERR_OID_VALIDATOR_STARTS_OR_ENDS_WITH_PERIOD.get(valueString, 121 argument.getIdentifierString())); 122 } 123 124 if (valueString.contains("..")) 125 { 126 throw new ArgumentException( 127 ERR_OID_VALIDATOR_CONSECUTIVE_PERIODS.get(valueString, 128 argument.getIdentifierString())); 129 } 130 131 final OID oid = new OID(valueString); 132 if (! oid.isValidNumericOID()) 133 { 134 throw new ArgumentException( 135 ERR_OID_VALIDATOR_ILLEGAL_CHARACTER.get(valueString, 136 argument.getIdentifierString())); 137 } 138 139 if (! isStrict) 140 { 141 return; 142 } 143 144 final List<Integer> components = oid.getComponents(); 145 if (components.size() < 2) 146 { 147 throw new ArgumentException( 148 ERR_OID_VALIDATOR_NOT_ENOUGH_COMPONENTS.get(valueString, 149 argument.getIdentifierString())); 150 } 151 152 final int firstComponent = components.get(0); 153 final int secondComponent = components.get(1); 154 switch (firstComponent) 155 { 156 case 0: 157 case 1: 158 if (secondComponent > 39) 159 { 160 throw new ArgumentException( 161 ERR_OID_VALIDATOR_ILLEGAL_SECOND_COMPONENT.get(valueString, 162 argument.getIdentifierString())); 163 } 164 break; 165 166 case 2: 167 // We don't need to do any more validation. 168 break; 169 170 default: 171 // Invalid value for the first component. 172 throw new ArgumentException( 173 ERR_OID_VALIDATOR_ILLEGAL_FIRST_COMPONENT.get(valueString, 174 argument.getIdentifierString())); 175 } 176 } 177 178 179 180 /** 181 * Retrieves a string representation of this argument value validator. 182 * 183 * @return A string representation of this argument value validator. 184 */ 185 @Override() 186 public String toString() 187 { 188 final StringBuilder buffer = new StringBuilder(); 189 toString(buffer); 190 return buffer.toString(); 191 } 192 193 194 195 /** 196 * Appends a string representation of this argument value validator to the 197 * provided buffer. 198 * 199 * @param buffer The buffer to which the string representation should be 200 * appended. 201 */ 202 public void toString(final StringBuilder buffer) 203 { 204 buffer.append("OIDArgumentValueValidator(isStrict="); 205 buffer.append(isStrict); 206 buffer.append(')'); 207 } 208}