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.*; 022import com.fasterxml.jackson.annotation.JsonAnySetter; 023import com.fasterxml.jackson.annotation.JsonIgnore; 024import com.fasterxml.jackson.annotation.JsonValue; 025import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 026 027import java.util.Map; 028import java.util.Objects; 029import java.util.Set; 030import java.util.TreeMap; 031 032/** 033 * Class that represents API descriptor's Service {@link Resource} definitions. 034 */ 035@JsonDeserialize(builder = Services.Builder.class) 036public final class Services { 037 038 private final Map<String, Resource> services; 039 040 private Services(Builder builder) { 041 this.services = builder.services; 042 } 043 044 /** 045 * Gets a {@code Map} of service-names to {@link Resource}s. 046 * This method is currently only used for JSON serialization. 047 * 048 * @return {@code Map} of service-names to {@link Resource}s. 049 */ 050 @JsonValue 051 protected Map<String, Resource> getServices() { 052 return services; 053 } 054 055 /** 056 * Gets the {@link Resource} for a given service-name. 057 * 058 * @param name Service name 059 * @return {@link Schema} or {@code null} if does-not-exist. 060 */ 061 @JsonIgnore 062 public Resource get(String name) { 063 return services.get(name); 064 } 065 066 /** 067 * Returns all {@link Services} names. 068 * 069 * @return All {@link Services} names. 070 */ 071 @JsonIgnore 072 public Set<String> getNames() { 073 return services.keySet(); 074 } 075 076 /** 077 * Create a new Builder for Services. 078 * 079 * @return Builder 080 */ 081 082 public static Builder services() { 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 Services services1 = (Services) o; 095 return Objects.equals(services, services1.services); 096 } 097 098 @Override 099 public int hashCode() { 100 return Objects.hash(services); 101 } 102 103 /** 104 * Builder to help construct the Services. 105 */ 106 public static final class Builder { 107 108 private final Map<String, Resource> services = new TreeMap<>(); 109 110 /** 111 * Private default constructor. 112 */ 113 private Builder() { 114 } 115 116 /** 117 * Adds a {@link Resource}. 118 * 119 * @param name Service name 120 * @param resource {@link Resource} 121 * @return Builder 122 */ 123 @JsonAnySetter 124 public Builder put(String name, Resource resource) { 125 if (isEmpty(name) || containsWhitespace(name)) { 126 throw new IllegalArgumentException( 127 "Resource name is required, must not be blank, and must not contain " + 128 "whitespace; given: '" + name + "'"); 129 } 130 if (services.containsKey(name) && !services.get(name).equals(resource)) { 131 throw new IllegalStateException( 132 "Resource name already exists but Resource objects are not equal; " + 133 "given: '" + name + "'"); 134 } 135 136 services.put(name, checkNotNull(resource)); 137 return this; 138 } 139 140 /** 141 * Builds the Definitions instance. 142 * 143 * @return Definitions instance 144 */ 145 public Services build() { 146 return new Services(this); 147 } 148 } 149 150 151}