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 java.io.Serializable; 022import java.security.SecureRandom; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.List; 027 028import net.minidev.json.JSONAware; 029import net.minidev.json.JSONValue; 030 031import com.nimbusds.jose.util.Base64URL; 032import com.nimbusds.oauth2.sdk.util.StringUtils; 033 034 035/** 036 * The base class for representing identifiers and identities. Provides 037 * constructors that generate Base64URL-encoded secure random identifier 038 * values. 039 * 040 * <p>Extending classes must override the {@link #equals} method. 041 */ 042public class Identifier implements Serializable, Comparable<Identifier>, JSONAware { 043 044 045 private static final long serialVersionUID = 365052911829193101L; 046 047 048 /** 049 * The default byte length of generated identifiers. 050 */ 051 public static final int DEFAULT_BYTE_LENGTH = 32; 052 053 054 /** 055 * Returns a string list representation of the specified identifier 056 * collection. 057 * 058 * @param ids The identifiers, {@code null} if not specified. 059 * 060 * @return The string list, empty list if not specified. 061 */ 062 public static List<String> toStringList(final Collection<? extends Identifier> ids) { 063 if (ids == null) { 064 return Collections.emptyList(); 065 } 066 List<String> stringList = new ArrayList<>(ids.size()); 067 for (Identifier id: ids) { 068 stringList.add(id.getValue()); 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 identifier value. Must not be {@code null} or empty 090 * string. 091 */ 092 public Identifier(final String value) { 093 094 if (StringUtils.isBlank(value)) 095 throw new IllegalArgumentException("The value must not be null or empty string"); 096 097 this.value = value; 098 } 099 100 101 /** 102 * Creates a new identifier with a randomly generated value of the 103 * specified byte length, Base64URL-encoded. 104 * 105 * @param byteLength The byte length of the value to generate. Must be 106 * greater than one. 107 */ 108 public Identifier(final int byteLength) { 109 110 if (byteLength < 1) 111 throw new IllegalArgumentException("The byte length must be a positive integer"); 112 113 byte[] n = new byte[byteLength]; 114 115 secureRandom.nextBytes(n); 116 117 value = Base64URL.encode(n).toString(); 118 } 119 120 121 /** 122 * Creates a new identifier with a randomly generated 256-bit 123 * (32-byte) value, Base64URL-encoded. 124 */ 125 public Identifier() { 126 127 this(DEFAULT_BYTE_LENGTH); 128 } 129 130 131 /** 132 * Returns the value of this identifier. 133 * 134 * @return The value. 135 */ 136 public String getValue() { 137 138 return value; 139 } 140 141 142 /** 143 * Returns the JSON string representation of this identifier. 144 * 145 * @return The JSON string. 146 */ 147 @Override 148 public String toJSONString() { 149 150 return "\"" + JSONValue.escape(value) + '"'; 151 } 152 153 154 /** 155 * @see #getValue 156 */ 157 @Override 158 public String toString() { 159 160 return getValue(); 161 } 162 163 164 @Override 165 public int compareTo(final Identifier other) { 166 167 return getValue().compareTo(other.getValue()); 168 } 169 170 171 @Override 172 public boolean equals(final Object o) { 173 if (this == o) return true; 174 if (o == null || getClass() != o.getClass()) return false; 175 176 Identifier that = (Identifier) o; 177 178 return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; 179 180 } 181 182 183 @Override 184 public int hashCode() { 185 return getValue() != null ? getValue().hashCode() : 0; 186 } 187}