View Javadoc
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 &lt;&lt; 0<br>
30   * Flag 2 = 1 &lt;&lt; 1<br>
31   * Flag 3 = 1 &lt;&lt; 2<br>
32   * Flag 4 = 1 &lt;&lt; 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       * @since 1.1.1
66       */
67      public void clear() {
68          flags = 0;
69      }
70  
71      /**
72       * Clone this Flags object.
73       *
74       * @return a copy of this object.
75       * @see Object#clone()
76       */
77      @Override
78      public Object clone() {
79          try {
80              return super.clone();
81          } catch (final CloneNotSupportedException e) {
82              throw new UnsupportedOperationException("Couldn't clone Flags object.", e);
83          }
84      }
85  
86      /**
87       * Tests if two Flags objects are in the same state.
88       * @param obj object being tested
89       * @see Object#equals(Object)
90       * @return whether the objects are equal.
91       */
92      @Override
93      public boolean equals(final Object obj) {
94          if (this == obj) {
95              return true;
96          }
97          if (!(obj instanceof Flags)) {
98              return false;
99          }
100         final Flags other = (Flags) obj;
101         return flags == other.flags;
102     }
103 
104     /**
105      * Returns the current flags.
106      *
107      * @return collection of boolean flags represented.
108      */
109     public long getFlags() {
110         return flags;
111     }
112 
113     /**
114      * The hash code is based on the current state of the flags.
115      * @see Object#hashCode()
116      * @return the hash code for this object.
117      */
118     @Override
119     public int hashCode() {
120         return (int) flags;
121     }
122 
123     /**
124      * Tests whether the given flag is off. If the flag is not a power of 2
125      * (for example, 3) this tests whether the combination of flags is off.
126      *
127      * @param flag Flag value to check.
128      * @return whether the specified flag value is off.
129      */
130     public boolean isOff(final long flag) {
131         return (flags & flag) == 0;
132     }
133 
134     /**
135      * Tests whether the given flag is on. If the flag is not a power of 2
136      * (for example, 3) this tests whether the combination of flags is on.
137      *
138      * @param flag Flag value to check.
139      * @return whether the specified flag value is on.
140      */
141     public boolean isOn(final long flag) {
142         return (flags & flag) == flag;
143     }
144 
145     /**
146      * Returns a 64 length String with the first flag on the right and the
147      * 64th flag on the left. A 1 indicates the flag is on, a 0 means it's
148      * off.
149      *
150      * @return string representation of this object.
151      */
152     @Override
153     public String toString() {
154         final StringBuilder bin = new StringBuilder(Long.toBinaryString(flags));
155         for (int i = 64 - bin.length(); i > 0; i--) { // CHECKSTYLE IGNORE MagicNumber
156             bin.insert(0, "0");
157         }
158         return bin.toString();
159     }
160 
161     /**
162      * Turns off the given flag. If the flag is not a power of 2 (for example, 3) this
163      * turns off multiple flags.
164      *
165      * @param flag Flag value to turn off.
166      */
167     public void turnOff(final long flag) {
168         flags &= ~flag;
169     }
170 
171     /**
172      * Turn off all flags.
173      */
174     public void turnOffAll() {
175         flags = 0;
176     }
177 
178     /**
179      * Turns on the given flag. If the flag is not a power of 2 (for example, 3) this
180      * turns on multiple flags.
181      *
182      * @param flag Flag value to turn on.
183      */
184     public void turnOn(final long flag) {
185         flags |= flag;
186     }
187 
188     /**
189      * Turn on all 64 flags.
190      */
191     public void turnOnAll() {
192         flags = 0xFFFFFFFFFFFFFFFFL;
193     }
194 
195 }