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    *      http://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   * @version $Revision: 1227719 $ $Date: 2012-01-05 18:45:51 +0100 (Do, 05 Jan 2012) $
40   */
41  public class Flags implements Serializable, Cloneable {
42  
43      private static final long serialVersionUID = 8481587558770237995L;
44  
45      /**
46       * Represents the current flag state.
47       */
48      private long flags = 0;
49  
50      /**
51       * Create a new Flags object.
52       */
53      public Flags() {
54          super();
55      }
56  
57      /**
58       * Initialize a new Flags object with the given flags.
59       *
60       * @param flags collection of boolean flags to represent.
61       */
62      public Flags(long flags) {
63          super();
64          this.flags = flags;
65      }
66  
67      /**
68       * Returns the current flags.
69       *
70       * @return collection of boolean flags represented.
71       */
72      public long getFlags() {
73          return this.flags;
74      }
75  
76      /**
77       * Tests whether the given flag is on.  If the flag is not a power of 2
78       * (ie. 3) this tests whether the combination of flags is on.
79       *
80       * @param flag Flag value to check.
81       *
82       * @return whether the specified flag value is on.
83       */
84      public boolean isOn(long flag) {
85          return (this.flags & flag) > 0;
86      }
87  
88      /**
89       * Tests whether the given flag is off.  If the flag is not a power of 2
90       * (ie. 3) this tests whether the combination of flags is off.
91       *
92       * @param flag Flag value to check.
93       *
94       * @return whether the specified flag value is off.
95       */
96      public boolean isOff(long flag) {
97          return (this.flags & flag) == 0;
98      }
99  
100     /**
101      * Turns on the given flag.  If the flag is not a power of 2 (ie. 3) this
102      * turns on multiple flags.
103      *
104      * @param flag Flag value to turn on.
105      */
106     public void turnOn(long flag) {
107         this.flags |= flag;
108     }
109 
110     /**
111      * Turns off the given flag.  If the flag is not a power of 2 (ie. 3) this
112      * turns off multiple flags.
113      *
114      * @param flag Flag value to turn off.
115      */
116     public void turnOff(long flag) {
117         this.flags &= ~flag;
118     }
119 
120     /**
121      * Turn off all flags.
122      */
123     public void turnOffAll() {
124         this.flags = 0;
125     }
126 
127     /**
128      * Turn off all flags.  This is a synonym for <code>turnOffAll()</code>.
129      * @since Validator 1.1.1
130      */
131     public void clear() {
132         this.flags = 0;
133     }
134 
135     /**
136      * Turn on all 64 flags.
137      */
138     public void turnOnAll() {
139         this.flags = Long.MAX_VALUE;
140     }
141 
142     /**
143      * Clone this Flags object.
144      *
145      * @return a copy of this object.
146      * @see java.lang.Object#clone()
147      */
148     public Object clone() {
149         try {
150             return super.clone();
151         } catch(CloneNotSupportedException e) {
152             throw new RuntimeException("Couldn't clone Flags object.");
153         }
154     }
155 
156     /**
157      * Tests if two Flags objects are in the same state.
158      * @param obj object being tested
159      * @see java.lang.Object#equals(java.lang.Object)
160      *
161      * @return whether the objects are equal.
162      */
163     public boolean equals(Object obj) {
164         if (!(obj instanceof Flags)) {
165             return false;
166         }
167 
168         if (obj == this) {
169             return true;
170         }
171 
172         Flags f = (Flags) obj;
173 
174         return this.flags == f.flags;
175     }
176 
177     /**
178      * The hash code is based on the current state of the flags.
179      * @see java.lang.Object#hashCode()
180      *
181      * @return the hash code for this object.
182      */
183     public int hashCode() {
184         return (int) this.flags;
185     }
186 
187     /**
188      * Returns a 64 length String with the first flag on the right and the
189      * 64th flag on the left.  A 1 indicates the flag is on, a 0 means it's
190      * off.
191      *
192      * @return string representation of this object.
193      */
194     public String toString() {
195         StringBuffer bin = new StringBuffer(Long.toBinaryString(this.flags));
196         for (int i = 64 - bin.length(); i > 0; i--) {
197             bin.insert(0, "0");
198         }
199         return bin.toString();
200     }
201 
202 }