1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.validator.util;
18
19 import java.io.Serializable;
20
21 /**
22 * Represents a collection of 64 boolean (on/off) flags. Individual flags
23 * are represented by powers of 2. For example,<br>
24 * Flag 1 = 1<br>
25 * Flag 2 = 2<br>
26 * Flag 3 = 4<br>
27 * Flag 4 = 8<br><br>
28 * or using shift operator to make numbering easier:<br>
29 * Flag 1 = 1 << 0<br>
30 * Flag 2 = 1 << 1<br>
31 * Flag 3 = 1 << 2<br>
32 * Flag 4 = 1 << 3<br>
33 *
34 * <p>
35 * There cannot be a flag with a value of 3 because that represents Flag 1
36 * and Flag 2 both being on/true.
37 * </p>
38 */
39 public class Flags implements Serializable, Cloneable {
40
41 private static final long serialVersionUID = 8481587558770237995L;
42
43 /**
44 * Represents the current flag state.
45 */
46 private long flags;
47
48 /**
49 * Create a new Flags object.
50 */
51 public Flags() {
52 }
53
54 /**
55 * Initialize a new Flags object with the given flags.
56 *
57 * @param flags collection of boolean flags to represent.
58 */
59 public Flags(final long flags) {
60 this.flags = flags;
61 }
62
63 /**
64 * Turn off all flags. This is a synonym for {@code turnOffAll()}.
65 *
66 * @since 1.1.1
67 */
68 public void clear() {
69 flags = 0;
70 }
71
72 /**
73 * Clone this Flags object.
74 *
75 * @return a copy of this object.
76 * @see Object#clone()
77 */
78 @Override
79 public Object clone() {
80 try {
81 return super.clone();
82 } catch (final CloneNotSupportedException e) {
83 throw new UnsupportedOperationException("Couldn't clone Flags object.", e);
84 }
85 }
86
87 /**
88 * Tests if two Flags objects are in the same state.
89 *
90 * @param obj object being tested
91 * @see Object#equals(Object)
92 * @return whether the objects are equal.
93 */
94 @Override
95 public boolean equals(final Object obj) {
96 if (this == obj) {
97 return true;
98 }
99 if (!(obj instanceof Flags)) {
100 return false;
101 }
102 final Flags other = (Flags) obj;
103 return flags == other.flags;
104 }
105
106 /**
107 * Returns the current flags.
108 *
109 * @return collection of boolean flags represented.
110 */
111 public long getFlags() {
112 return flags;
113 }
114
115 /**
116 * The hash code is based on the current state of the flags.
117 *
118 * @see Object#hashCode()
119 * @return the hash code for this object.
120 */
121 @Override
122 public int hashCode() {
123 return (int) flags;
124 }
125
126 /**
127 * Tests whether the given flag is off. If the flag is not a power of 2
128 * (for example, 3) this tests whether the combination of flags is off.
129 *
130 * @param flag Flag value to check.
131 * @return whether the specified flag value is off.
132 */
133 public boolean isOff(final long flag) {
134 return (flags & flag) == 0;
135 }
136
137 /**
138 * Tests whether the given flag is on. If the flag is not a power of 2
139 * (for example, 3) this tests whether the combination of flags is on.
140 *
141 * @param flag Flag value to check.
142 * @return whether the specified flag value is on.
143 */
144 public boolean isOn(final long flag) {
145 return (flags & flag) == flag;
146 }
147
148 /**
149 * Returns a 64 length String with the first flag on the right and the
150 * 64th flag on the left. A 1 indicates the flag is on, a 0 means it's
151 * off.
152 *
153 * @return string representation of this object.
154 */
155 @Override
156 public String toString() {
157 final StringBuilder bin = new StringBuilder(Long.toBinaryString(flags));
158 for (int i = 64 - bin.length(); i > 0; i--) { // CHECKSTYLE IGNORE MagicNumber
159 bin.insert(0, "0");
160 }
161 return bin.toString();
162 }
163
164 /**
165 * Turns off the given flag. If the flag is not a power of 2 (for example, 3) this
166 * turns off multiple flags.
167 *
168 * @param flag Flag value to turn off.
169 */
170 public void turnOff(final long flag) {
171 flags &= ~flag;
172 }
173
174 /**
175 * Turn off all flags.
176 */
177 public void turnOffAll() {
178 flags = 0;
179 }
180
181 /**
182 * Turns on the given flag. If the flag is not a power of 2 (for example, 3) this
183 * turns on multiple flags.
184 *
185 * @param flag Flag value to turn on.
186 */
187 public void turnOn(final long flag) {
188 flags |= flag;
189 }
190
191 /**
192 * Turn on all 64 flags.
193 */
194 public void turnOnAll() {
195 flags = 0xFFFFFFFFFFFFFFFFL;
196 }
197
198 }