001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.validator.util; 018 019import java.io.Serializable; 020 021/** 022 * Represents a collection of 64 boolean (on/off) flags. Individual flags 023 * are represented by powers of 2. For example,<br> 024 * Flag 1 = 1<br> 025 * Flag 2 = 2<br> 026 * Flag 3 = 4<br> 027 * Flag 4 = 8<br><br> 028 * or using shift operator to make numbering easier:<br> 029 * Flag 1 = 1 << 0<br> 030 * Flag 2 = 1 << 1<br> 031 * Flag 3 = 1 << 2<br> 032 * Flag 4 = 1 << 3<br> 033 * 034 * <p> 035 * There cannot be a flag with a value of 3 because that represents Flag 1 036 * and Flag 2 both being on/true. 037 * </p> 038 * 039 * @version $Revision$ 040 */ 041public class Flags implements Serializable, Cloneable { 042 043 private static final long serialVersionUID = 8481587558770237995L; 044 045 /** 046 * Represents the current flag state. 047 */ 048 private long flags = 0; 049 050 /** 051 * Create a new Flags object. 052 */ 053 public Flags() { 054 super(); 055 } 056 057 /** 058 * Initialize a new Flags object with the given flags. 059 * 060 * @param flags collection of boolean flags to represent. 061 */ 062 public Flags(long flags) { 063 super(); 064 this.flags = flags; 065 } 066 067 /** 068 * Returns the current flags. 069 * 070 * @return collection of boolean flags represented. 071 */ 072 public long getFlags() { 073 return this.flags; 074 } 075 076 /** 077 * Tests whether the given flag is on. If the flag is not a power of 2 078 * (ie. 3) this tests whether the combination of flags is on. 079 * 080 * @param flag Flag value to check. 081 * 082 * @return whether the specified flag value is on. 083 */ 084 public boolean isOn(long flag) { 085 return (this.flags & flag) == flag; 086 } 087 088 /** 089 * Tests whether the given flag is off. If the flag is not a power of 2 090 * (ie. 3) this tests whether the combination of flags is off. 091 * 092 * @param flag Flag value to check. 093 * 094 * @return whether the specified flag value is off. 095 */ 096 public boolean isOff(long flag) { 097 return (this.flags & flag) == 0; 098 } 099 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 = 0xFFFFFFFFFFFFFFFFl; 140 } 141 142 /** 143 * Clone this Flags object. 144 * 145 * @return a copy of this object. 146 * @see java.lang.Object#clone() 147 */ 148 @Override 149 public Object clone() { 150 try { 151 return super.clone(); 152 } catch(CloneNotSupportedException e) { 153 throw new RuntimeException("Couldn't clone Flags object."); 154 } 155 } 156 157 /** 158 * Tests if two Flags objects are in the same state. 159 * @param obj object being tested 160 * @see java.lang.Object#equals(java.lang.Object) 161 * 162 * @return whether the objects are equal. 163 */ 164 @Override 165 public boolean equals(Object obj) { 166 if (!(obj instanceof Flags)) { 167 return false; 168 } 169 170 if (obj == this) { 171 return true; 172 } 173 174 Flags f = (Flags) obj; 175 176 return this.flags == f.flags; 177 } 178 179 /** 180 * The hash code is based on the current state of the flags. 181 * @see java.lang.Object#hashCode() 182 * 183 * @return the hash code for this object. 184 */ 185 @Override 186 public int hashCode() { 187 return (int) this.flags; 188 } 189 190 /** 191 * Returns a 64 length String with the first flag on the right and the 192 * 64th flag on the left. A 1 indicates the flag is on, a 0 means it's 193 * off. 194 * 195 * @return string representation of this object. 196 */ 197 @Override 198 public String toString() { 199 StringBuilder bin = new StringBuilder(Long.toBinaryString(this.flags)); 200 for (int i = 64 - bin.length(); i > 0; i--) { // CHECKSTYLE IGNORE MagicNumber 201 bin.insert(0, "0"); 202 } 203 return bin.toString(); 204 } 205 206}