001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.id; 019 020 021import com.nimbusds.jose.util.Base64URL; 022import com.nimbusds.oauth2.sdk.util.StringUtils; 023import net.minidev.json.JSONAware; 024import net.minidev.json.JSONValue; 025 026import java.io.Serializable; 027import java.security.SecureRandom; 028import java.util.ArrayList; 029import java.util.Collection; 030import java.util.Collections; 031import java.util.List; 032 033 034/** 035 * The base class for representing identifiers. Provides constructors that 036 * generate Base64URL-encoded secure random identifier values. 037 * 038 * <p>Extending classes must override the {@link #equals} method. 039 */ 040public class Identifier implements Serializable, Comparable<Identifier>, JSONAware { 041 042 043 private static final long serialVersionUID = 365052911829193101L; 044 045 046 /** 047 * The default byte length of generated identifiers. 048 */ 049 public static final int DEFAULT_BYTE_LENGTH = 32; 050 051 052 /** 053 * Returns a string list representation of the specified identifier 054 * collection. Omits {@code null} items in the collection. 055 * 056 * @param ids The identifiers, {@code null} if not specified. 057 * 058 * @return The string list, empty list if not specified. 059 */ 060 public static List<String> toStringList(final Collection<? extends Identifier> ids) { 061 if (ids == null) { 062 return Collections.emptyList(); 063 } 064 List<String> stringList = new ArrayList<>(ids.size()); 065 for (Identifier id: ids) { 066 if (id != null) { 067 stringList.add(id.getValue()); 068 } 069 } 070 return stringList; 071 } 072 073 074 /** 075 * The secure random generator. 076 */ 077 protected static final SecureRandom secureRandom = new SecureRandom(); 078 079 080 /** 081 * The identifier value. 082 */ 083 private final String value; 084 085 086 /** 087 * Creates a new identifier with the specified value. 088 * 089 * @param value The value. Must not be {@code null} or empty string. 090 */ 091 public Identifier(final String value) { 092 093 if (StringUtils.isBlank(value)) 094 throw new IllegalArgumentException("The value must not be null or empty string"); 095 096 this.value = value; 097 } 098 099 100 /** 101 * Creates a new identifier with a randomly generated value of the 102 * specified byte length, Base64URL-encoded. 103 * 104 * @param byteLength The byte length of the value to generate. Must be 105 * greater than one. 106 */ 107 public Identifier(final int byteLength) { 108 109 if (byteLength < 1) 110 throw new IllegalArgumentException("The byte length must be a positive integer"); 111 112 byte[] n = new byte[byteLength]; 113 114 secureRandom.nextBytes(n); 115 116 value = Base64URL.encode(n).toString(); 117 } 118 119 120 /** 121 * Creates a new identifier with a randomly generated 256-bit 122 * (32-byte) value, Base64URL-encoded. 123 */ 124 public Identifier() { 125 126 this(DEFAULT_BYTE_LENGTH); 127 } 128 129 130 /** 131 * Returns the value of this identifier. 132 * 133 * @return The value. 134 */ 135 public String getValue() { 136 137 return value; 138 } 139 140 141 /** 142 * Returns the JSON string representation of this identifier. 143 * 144 * @return The JSON string. 145 */ 146 @Override 147 public String toJSONString() { 148 149 return "\"" + JSONValue.escape(value) + '"'; 150 } 151 152 153 /** 154 * @see #getValue 155 */ 156 @Override 157 public String toString() { 158 159 return getValue(); 160 } 161 162 163 @Override 164 public int compareTo(final Identifier other) { 165 166 return getValue().compareTo(other.getValue()); 167 } 168 169 170 @Override 171 public boolean equals(final Object o) { 172 if (this == o) return true; 173 if (o == null || getClass() != o.getClass()) return false; 174 175 Identifier that = (Identifier) o; 176 177 return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; 178 179 } 180 181 182 @Override 183 public int hashCode() { 184 return getValue() != null ? getValue().hashCode() : 0; 185 } 186}