2323
2424import java .io .Serializable ;
2525import java .util .Arrays ;
26+ import java .util .Collection ;
2627import java .util .HashMap ;
2728import java .util .HashSet ;
29+ import java .util .LinkedList ;
30+ import java .util .List ;
2831import java .util .Map ;
2932import java .util .Objects ;
3033import java .util .Set ;
@@ -65,8 +68,14 @@ protected Builder() {}
6568
6669 /**
6770 * Replaces the builder's map of bindings with the given map of bindings.
71+ *
72+ * @throws IllegalArgumentException if the provided map is null or contain any null values
6873 */
6974 public final B bindings (Map <R , Set <Identity >> bindings ) {
75+ checkArgument (bindings != null , "The provided map of bindings cannot be null." );
76+ for (Map .Entry <R , Set <Identity >> binding : bindings .entrySet ()) {
77+ verifyBinding (binding .getKey (), binding .getValue ());
78+ }
7079 this .bindings .clear ();
7180 for (Map .Entry <R , Set <Identity >> binding : bindings .entrySet ()) {
7281 this .bindings .put (binding .getKey (), new HashSet <Identity >(binding .getValue ()));
@@ -78,10 +87,12 @@ public final B bindings(Map<R, Set<Identity>> bindings) {
7887 * Adds a binding to the policy.
7988 *
8089 * @throws IllegalArgumentException if the policy already contains a binding with the same role
90+ * or if the role or any identities are null
8191 */
8292 public final B addBinding (R role , Set <Identity > identities ) {
93+ verifyBinding (role , identities );
8394 checkArgument (!bindings .containsKey (role ),
84- "The policy already contains a binding with the role " + role .toString ());
95+ "The policy already contains a binding with the role " + role .toString () + "." );
8596 bindings .put (role , new HashSet <Identity >(identities ));
8697 return self ();
8798 }
@@ -90,15 +101,23 @@ public final B addBinding(R role, Set<Identity> identities) {
90101 * Adds a binding to the policy.
91102 *
92103 * @throws IllegalArgumentException if the policy already contains a binding with the same role
104+ * or if the role or any identities are null
93105 */
94106 public final B addBinding (R role , Identity first , Identity ... others ) {
95- checkArgument (!bindings .containsKey (role ),
96- "The policy already contains a binding with the role " + role .toString ());
97107 HashSet <Identity > identities = new HashSet <>();
98108 identities .add (first );
99109 identities .addAll (Arrays .asList (others ));
100- bindings .put (role , identities );
101- return self ();
110+ return addBinding (role , identities );
111+ }
112+
113+ private void verifyBinding (R role , Collection <Identity > identities ) {
114+ checkArgument (role != null , "The role cannot be null." );
115+ verifyIdentities (identities );
116+ }
117+
118+ private void verifyIdentities (Collection <Identity > identities ) {
119+ checkArgument (identities != null , "A role cannot be assigned to a null set of identities." );
120+ checkArgument (!identities .contains (null ), "Null identities are not permitted." );
102121 }
103122
104123 /**
@@ -113,13 +132,16 @@ public final B removeBinding(R role) {
113132 * Adds one or more identities to an existing binding.
114133 *
115134 * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified
116- * role
135+ * role or any identities are null
117136 */
118137 public final B addIdentity (R role , Identity first , Identity ... others ) {
119- checkArgument (bindings .containsKey (role ), "The policy doesn't contain the specified role." );
120- Set <Identity > identities = bindings .get (role );
121- identities .add (first );
122- identities .addAll (Arrays .asList (others ));
138+ checkArgument (bindings .containsKey (role ),
139+ "The policy doesn't contain the role " + role .toString () + "." );
140+ List <Identity > toAdd = new LinkedList <>();
141+ toAdd .add (first );
142+ toAdd .addAll (Arrays .asList (others ));
143+ verifyIdentities (toAdd );
144+ bindings .get (role ).addAll (toAdd );
123145 return self ();
124146 }
125147
@@ -130,7 +152,8 @@ public final B addIdentity(R role, Identity first, Identity... others) {
130152 * role
131153 */
132154 public final B removeIdentity (R role , Identity first , Identity ... others ) {
133- checkArgument (bindings .containsKey (role ), "The policy doesn't contain the specified role." );
155+ checkArgument (bindings .containsKey (role ),
156+ "The policy doesn't contain the role " + role .toString () + "." );
134157 bindings .get (role ).remove (first );
135158 bindings .get (role ).removeAll (Arrays .asList (others ));
136159 return self ();
@@ -179,6 +202,11 @@ protected IamPolicy(Builder<R, ? extends Builder<R, ?>> builder) {
179202 this .version = builder .version ;
180203 }
181204
205+ /**
206+ * Returns a builder containing the properties of this IAM Policy.
207+ */
208+ public abstract Builder <R , ? extends Builder <R , ?>> toBuilder ();
209+
182210 /**
183211 * The map of bindings that comprises the policy.
184212 */
0 commit comments