1 /*
2 * The contents of this file are subject to the terms of the Common Development and
3 * Distribution License (the License). You may not use this file except in compliance with the
4 * License.
5 *
6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7 * specific language governing permission and limitations under the License.
8 *
9 * When distributing Covered Software, include this CDDL Header Notice in each file and include
10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11 * Header, with the fields enclosed by brackets [] replaced by your own identifying
12 * information: "Portions copyright [year] [name of copyright owner]".
13 *
14 * Copyright 2016 ForgeRock AS.
15 * Portions Copyright 2018 Wren Security
16 */
17
18 package org.forgerock.api.models;
19
20 import static org.forgerock.api.util.ValidationUtil.*;
21 import static org.forgerock.util.Reject.*;
22 import com.fasterxml.jackson.annotation.JsonAnySetter;
23 import com.fasterxml.jackson.annotation.JsonIgnore;
24 import com.fasterxml.jackson.annotation.JsonValue;
25 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
26
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Set;
30 import java.util.TreeMap;
31
32 /**
33 * Class that represents API descriptor's Service {@link Resource} definitions.
34 */
35 @JsonDeserialize(builder = Services.Builder.class)
36 public final class Services {
37
38 private final Map<String, Resource> services;
39
40 private Services(Builder builder) {
41 this.services = builder.services;
42 }
43
44 /**
45 * Gets a {@code Map} of service-names to {@link Resource}s.
46 * This method is currently only used for JSON serialization.
47 *
48 * @return {@code Map} of service-names to {@link Resource}s.
49 */
50 @JsonValue
51 protected Map<String, Resource> getServices() {
52 return services;
53 }
54
55 /**
56 * Gets the {@link Resource} for a given service-name.
57 *
58 * @param name Service name
59 * @return {@link Schema} or {@code null} if does-not-exist.
60 */
61 @JsonIgnore
62 public Resource get(String name) {
63 return services.get(name);
64 }
65
66 /**
67 * Returns all {@link Services} names.
68 *
69 * @return All {@link Services} names.
70 */
71 @JsonIgnore
72 public Set<String> getNames() {
73 return services.keySet();
74 }
75
76 /**
77 * Create a new Builder for Services.
78 *
79 * @return Builder
80 */
81
82 public static Builder services() {
83 return new Builder();
84 }
85
86 @Override
87 public boolean equals(Object o) {
88 if (this == o) {
89 return true;
90 }
91 if (o == null || getClass() != o.getClass()) {
92 return false;
93 }
94 Services services1 = (Services) o;
95 return Objects.equals(services, services1.services);
96 }
97
98 @Override
99 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 }