001/* 002 * Copyright 2015-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2019 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.io.Serializable; 026import java.net.URI; 027import java.util.Collection; 028import java.util.Collections; 029import java.util.Iterator; 030import java.util.LinkedHashSet; 031import java.util.Set; 032 033import com.unboundid.util.Debug; 034import com.unboundid.util.NotMutable; 035import com.unboundid.util.StaticUtils; 036import com.unboundid.util.ThreadSafety; 037import com.unboundid.util.ThreadSafetyLevel; 038 039import static com.unboundid.util.args.ArgsMessages.*; 040 041 042 043/** 044 * This class provides an implementation of an argument value validator that is 045 * expected to be used with a string argument and ensures that all values for 046 * the argument are valid URLs. It can optionally restrict the URLs to a 047 * specified set of schemes. 048 */ 049@NotMutable() 050@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 051public final class URLArgumentValueValidator 052 extends ArgumentValueValidator 053 implements Serializable 054{ 055 /** 056 * The serial version UID for this serializable class. 057 */ 058 private static final long serialVersionUID = -4431100566624433212L; 059 060 061 062 // The set of schemes allowed to be used in URLs. 063 private final Set<String> allowedSchemes; 064 065 066 067 /** 068 * Creates a new instance of this URL argument value validator that will 069 * accept values that are URLs with any of the specified schemes. 070 * 071 * @param allowedSchemes The names of the schemes for the URLs that will be 072 * accepted. It may be {@code null} or empty if any 073 * scheme will be accepted. 074 */ 075 public URLArgumentValueValidator(final String... allowedSchemes) 076 { 077 this(StaticUtils.toList(allowedSchemes)); 078 } 079 080 081 082 /** 083 * Creates a new instance of this URL argument value validator that will 084 * accept values that are URLs with any of the specified schemes. 085 * 086 * @param allowedSchemes The names of the schemes for the URLs that will be 087 * accepted. It may be {@code null} or empty if any 088 * scheme will be accepted. 089 */ 090 public URLArgumentValueValidator(final Collection<String> allowedSchemes) 091 { 092 if (allowedSchemes == null) 093 { 094 this.allowedSchemes = Collections.emptySet(); 095 } 096 else 097 { 098 this.allowedSchemes = 099 Collections.unmodifiableSet(new LinkedHashSet<>(allowedSchemes)); 100 } 101 } 102 103 104 105 /** 106 * Retrieves the names of the schemes for the URLs that will be accepted. 107 * 108 * @return The names of the schemes for the URLs that will be accepted, or 109 * an empty set if URLs will be allowed to have any scheme. 110 */ 111 public Set<String> getAllowedSchemes() 112 { 113 return allowedSchemes; 114 } 115 116 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override() 122 public void validateArgumentValue(final Argument argument, 123 final String valueString) 124 throws ArgumentException 125 { 126 final URI uri; 127 try 128 { 129 uri = new URI(valueString); 130 } 131 catch (final Exception e) 132 { 133 Debug.debugException(e); 134 throw new ArgumentException( 135 ERR_URL_VALIDATOR_VALUE_NOT_URL.get(valueString, 136 argument.getIdentifierString(), 137 StaticUtils.getExceptionMessage(e)), 138 e); 139 } 140 141 if (uri.getScheme() == null) 142 { 143 throw new ArgumentException(ERR_URL_VALIDATOR_MISSING_SCHEME.get( 144 valueString, argument.getIdentifierString())); 145 } 146 147 if ((! allowedSchemes.isEmpty()) && 148 (! allowedSchemes.contains(uri.getScheme()))) 149 { 150 throw new ArgumentException( 151 ERR_URL_VALIDATOR_UNACCEPTABLE_SCHEME.get(valueString, 152 argument.getIdentifierString(), uri.getScheme())); 153 } 154 } 155 156 157 158 /** 159 * Retrieves a string representation of this argument value validator. 160 * 161 * @return A string representation of this argument value validator. 162 */ 163 @Override() 164 public String toString() 165 { 166 final StringBuilder buffer = new StringBuilder(); 167 toString(buffer); 168 return buffer.toString(); 169 } 170 171 172 173 /** 174 * Appends a string representation of this argument value validator to the 175 * provided buffer. 176 * 177 * @param buffer The buffer to which the string representation should be 178 * appended. 179 */ 180 public void toString(final StringBuilder buffer) 181 { 182 buffer.append("URLArgumentValueValidator("); 183 184 if (allowedSchemes != null) 185 { 186 buffer.append("allowedSchemes={"); 187 188 final Iterator<String> iterator = allowedSchemes.iterator(); 189 while (iterator.hasNext()) 190 { 191 buffer.append('\''); 192 buffer.append(iterator.next()); 193 buffer.append('\''); 194 195 if (iterator.hasNext()) 196 { 197 buffer.append(", "); 198 } 199 } 200 201 buffer.append('}'); 202 } 203 204 buffer.append(')'); 205 } 206}