001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2016 ForgeRock AS. 015 * Portions Copyright 2018 Wren Security 016 */ 017 018package org.forgerock.api.models; 019 020import static org.forgerock.api.util.ValidationUtil.*; 021import static org.forgerock.util.Reject.*; 022 023import java.util.HashMap; 024import java.util.Map; 025import java.util.Objects; 026import java.util.Set; 027 028import com.fasterxml.jackson.annotation.JsonAnySetter; 029import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 030 031import com.fasterxml.jackson.annotation.JsonIgnore; 032import com.fasterxml.jackson.annotation.JsonValue; 033 034/** 035 * Class that represents API descriptor {@link Schema} definitions. 036 */ 037@JsonDeserialize(builder = Definitions.Builder.class) 038public final class Definitions { 039 040 private final Map<String, Schema> definitions; 041 042 private Definitions(Builder builder) { 043 this.definitions = builder.definitions; 044 } 045 046 /** 047 * Gets a {@code Map} of schema-names to {@link Schema}s. This method is currently only used for JSON serialization. 048 * 049 * @return {@code Map} of schema-names to {@link Schema}s. 050 */ 051 @JsonValue 052 protected Map<String, Schema> getDefinitions() { 053 return definitions; 054 } 055 056 /** 057 * Gets the {@link Schema} for a given Schema-name. 058 * 059 * @param name Schema name 060 * @return {@link Schema} or {@code null} if does-not-exist. 061 */ 062 @JsonIgnore 063 public Schema get(String name) { 064 return definitions.get(name); 065 } 066 067 /** 068 * Returns all {@link Schema} names. 069 * 070 * @return All {@link Schema} names. 071 */ 072 @JsonIgnore 073 public Set<String> getNames() { 074 return definitions.keySet(); 075 } 076 077 /** 078 * Create a new Builder for Definitions. 079 * 080 * @return Builder 081 */ 082 public static Builder definitions() { 083 return new Builder(); 084 } 085 086 @Override 087 public boolean equals(Object o) { 088 if (this == o) { 089 return true; 090 } 091 if (o == null || getClass() != o.getClass()) { 092 return false; 093 } 094 Definitions that = (Definitions) o; 095 return Objects.equals(definitions, that.definitions); 096 } 097 098 @Override 099 public int hashCode() { 100 return Objects.hash(definitions); 101 } 102 103 /** 104 * Builder to help construct the Definitions. 105 */ 106 public static final class Builder { 107 108 private final Map<String, Schema> definitions = new HashMap<>(); 109 110 /** 111 * Private default constructor. 112 */ 113 private Builder() { 114 } 115 116 /** 117 * Adds a {@link Schema}. 118 * 119 * @param name Schema name 120 * @param schema {@link Schema} 121 * @return Builder 122 */ 123 @JsonAnySetter 124 public Builder put(String name, Schema schema) { 125 if (isEmpty(name) || containsWhitespace(name)) { 126 throw new IllegalArgumentException( 127 "Schema name is required, must not be blank, and must not contain " + 128 "whitespace; given: '" + name + "'"); 129 } 130 if (definitions.containsKey(name) && !definitions.get(name).equals(schema)) { 131 throw new IllegalStateException( 132 "Schema name already exists but Schema objects are not equal; " + 133 "given: '" + name + "'"); 134 } 135 136 definitions.put(name, checkNotNull(schema)); 137 return this; 138 } 139 140 /** 141 * Builds the Definitions instance. 142 * 143 * @return Definitions instance 144 */ 145 public Definitions build() { 146 return new Definitions(this); 147 } 148 } 149 150}