View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.aws.ec2.model.security;
17  
18  import static com.google.common.collect.Lists.newArrayList;
19  import static org.kuali.common.util.ListUtils.equalElements;
20  
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.List;
24  
25  import org.hibernate.validator.constraints.NotEmpty;
26  import org.kuali.common.core.build.ValidatingBuilder;
27  import org.kuali.common.core.validate.annotation.IdiotProofImmutable;
28  import org.kuali.common.core.validate.annotation.ValidPort;
29  import org.kuali.common.util.ObjectUtils;
30  
31  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
32  import com.google.common.base.Objects;
33  import com.google.common.collect.ComparisonChain;
34  import com.google.common.collect.ImmutableList;
35  
36  /**
37   * This is an immutable, slimmed down, version of the comparable AWS permissions object. Only supports a single port (no port ranges) and CIDR notations.
38   */
39  @IdiotProofImmutable
40  @JsonDeserialize(builder = Permission.Builder.class)
41  public final class Permission {
42  
43  	@ValidPort
44  	private final int port;
45  
46  	private final Protocol protocol;
47  
48  	@NotEmpty
49  	private final ImmutableList<String> cidrNotations;
50  
51  	public static Permission create(int port) {
52  		return builder(port).build();
53  	}
54  
55  	public static Builder builder(int port) {
56  		return new Builder(port);
57  	}
58  
59  	public static class Builder extends ValidatingBuilder<Permission> {
60  
61  		// Required
62  		private final int port;
63  
64  		// Optional
65  		private List<String> cidrNotations = newArrayList(CIDR.ANY.getNotation());
66  		private Protocol protocol = Protocol.TCP;
67  
68  		public Builder(int port) {
69  			this.port = port;
70  		}
71  
72  		public Builder withCidrNotations(List<String> cidrNotations) {
73  			this.cidrNotations = cidrNotations;
74  			return this;
75  		}
76  
77  		public Builder withProtocol(Protocol protocol) {
78  			this.protocol = protocol;
79  			return this;
80  		}
81  
82  		@Override
83  		public Permission build() {
84  			// Changing this has implications for equals(), be careful
85  			this.cidrNotations = newArrayList(cidrNotations);
86  			Collections.sort(cidrNotations);
87  			return validate(new Permission(this));
88  		}
89  	}
90  
91  	private Permission(Builder builder) {
92  		this.protocol = builder.protocol;
93  		this.port = builder.port;
94  		this.cidrNotations = ImmutableList.copyOf(builder.cidrNotations);
95  	}
96  
97  	public Protocol getProtocol() {
98  		return protocol;
99  	}
100 
101 	public int getPort() {
102 		return port;
103 	}
104 
105 	public List<String> getCidrNotations() {
106 		return cidrNotations;
107 	}
108 
109 	@Override
110 	public int hashCode() {
111 		final int prime = 31;
112 		int result = Objects.hashCode(port, protocol);
113 		for (String notation : cidrNotations) {
114 			result = result * prime + notation.hashCode();
115 		}
116 		return result;
117 	}
118 
119 	@Override
120 	public boolean equals(Object object) {
121 
122 		// They are the same object
123 		if (this == object) {
124 			return true;
125 		}
126 
127 		// Make sure object isn't null and is a Permission object
128 		if (ObjectUtils.notEqual(this, object)) {
129 			return false;
130 		}
131 
132 		// Cast to a Permission object
133 		Permission a = this;
134 		Permission b = (Permission) object;
135 
136 		// If they both have the exact same list of CIDR notations, they are equal
137 		// This only works because Builder.build() sorts the CIDR notation list
138 		return Objects.equal(a.port, b.port) && Objects.equal(a.protocol, b.protocol) && equalElements(a.cidrNotations, b.cidrNotations);
139 
140 	}
141 
142 	// Singleton enum pattern
143 	public enum DefaultComparator implements Comparator<Permission> {
144 		INSTANCE;
145 
146 		@Override
147 		public int compare(Permission one, Permission two) {
148 			return ComparisonChain.start().compare(one.getPort(), two.getPort()).compare(one.getProtocol(), two.getProtocol()).result();
149 		}
150 	}
151 
152 }