• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // =================================================================================================
2 // ADOBE SYSTEMS INCORPORATED
3 // Copyright 2006 Adobe Systems Incorporated
4 // All Rights Reserved
5 //
6 // NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
7 // of the Adobe license agreement accompanying it.
8 // =================================================================================================
9 
10 package com.adobe.xmp.options;
11 
12 import java.util.HashMap;
13 import java.util.Map;
14 
15 import com.adobe.xmp.XMPError;
16 import com.adobe.xmp.XMPException;
17 
18 /**
19  * The base class for a collection of 32 flag bits. Individual flags are defined as enum value bit
20  * masks. Inheriting classes add convenience accessor methods.
21  *
22  * @since 24.01.2006
23  */
24 public abstract class Options
25 {
26 	/** the internal int containing all options */
27 	private int options = 0;
28 	/** a map containing the bit names */
29 	private Map optionNames = null;
30 
31 
32 	/**
33 	 * The default constructor.
34 	 */
Options()35 	public Options()
36 	{
37 		// EMTPY
38 	}
39 
40 
41 	/**
42 	 * Constructor with the options bit mask.
43 	 *
44 	 * @param options the options bit mask
45 	 * @throws XMPException If the options are not correct
46 	 */
Options(int options)47 	public Options(int options) throws XMPException
48 	{
49 		assertOptionsValid(options);
50 		setOptions(options);
51 	}
52 
53 
54 	/**
55 	 * Resets the options.
56 	 */
clear()57 	public void clear()
58 	{
59 		options = 0;
60 	}
61 
62 
63 	/**
64 	 * @param optionBits an option bitmask
65 	 * @return Returns true, if this object is equal to the given options.
66 	 */
isExactly(int optionBits)67 	public boolean isExactly(int optionBits)
68 	{
69 		return getOptions() == optionBits;
70 	}
71 
72 
73 	/**
74 	 * @param optionBits an option bitmask
75 	 * @return Returns true, if this object contains all given options.
76 	 */
containsAllOptions(int optionBits)77 	public boolean containsAllOptions(int optionBits)
78 	{
79 		return (getOptions() & optionBits) == optionBits;
80 	}
81 
82 
83 	/**
84 	 * @param optionBits an option bitmask
85 	 * @return Returns true, if this object contain at least one of the given options.
86 	 */
containsOneOf(int optionBits)87 	public boolean containsOneOf(int optionBits)
88 	{
89 		return ((getOptions()) & optionBits) != 0;
90 	}
91 
92 
93 	/**
94 	 * @param optionBit the binary bit or bits that are requested
95 	 * @return Returns if <emp>all</emp> of the requested bits are set or not.
96 	 */
getOption(int optionBit)97 	protected boolean getOption(int optionBit)
98 	{
99 		return (options & optionBit) != 0;
100 	}
101 
102 
103 	/**
104 	 * @param optionBits the binary bit or bits that shall be set to the given value
105 	 * @param value the boolean value to set
106 	 */
setOption(int optionBits, boolean value)107 	public void setOption(int optionBits, boolean value)
108 	{
109 		options = value ? options | optionBits : options & ~optionBits;
110 	}
111 
112 
113 	/**
114 	 * Is friendly to access it during the tests.
115 	 * @return Returns the options.
116 	 */
getOptions()117 	public int getOptions()
118 	{
119 		return options;
120 	}
121 
122 
123 	/**
124 	 * @param options The options to set.
125 	 * @throws XMPException
126 	 */
setOptions(int options)127 	public void setOptions(int options) throws XMPException
128 	{
129 		assertOptionsValid(options);
130 		this.options = options;
131 	}
132 
133 
134 	/**
135 	 * @see Object#equals(Object)
136 	 */
equals(Object obj)137 	public boolean equals(Object obj)
138 	{
139 		return getOptions() == ((Options) obj).getOptions();
140 	}
141 
142 
143 	/**
144 	 * @see java.lang.Object#hashCode()
145 	 */
hashCode()146 	public int hashCode()
147 	{
148 		return getOptions();
149 	}
150 
151 
152 	/**
153 	 * Creates a human readable string from the set options. <em>Note:</em> This method is quite
154 	 * expensive and should only be used within tests or as
155 	 * @return Returns a String listing all options that are set to <code>true</code> by their name,
156 	 * like &quot;option1 | option4&quot;.
157 	 */
getOptionsString()158 	public String getOptionsString()
159 	{
160 		if (options != 0)
161 		{
162 			StringBuffer sb = new StringBuffer();
163 			int theBits = options;
164 			while (theBits != 0)
165 			{
166 				int oneLessBit = theBits & (theBits - 1); // clear rightmost one bit
167 				int singleBit = theBits ^ oneLessBit;
168 				String bitName = getOptionName(singleBit);
169 				sb.append(bitName);
170 				if (oneLessBit != 0)
171 				{
172 					sb.append(" | ");
173 				}
174 				theBits = oneLessBit;
175 			}
176 			return sb.toString();
177 		}
178 		else
179 		{
180 			return "<none>";
181 		}
182 	}
183 
184 
185 	/**
186 	 * @return Returns the options as hex bitmask.
187 	 */
toString()188 	public String toString()
189 	{
190 		return "0x" + Integer.toHexString(options);
191 	}
192 
193 
194 	/**
195 	 * To be implemeted by inheritants.
196 	 * @return Returns a bit mask where all valid option bits are set.
197 	 */
getValidOptions()198 	protected abstract int getValidOptions();
199 
200 
201 	/**
202 	 * To be implemeted by inheritants.
203 	 * @param option a single, valid option bit.
204 	 * @return Returns a human readable name for an option bit.
205 	 */
defineOptionName(int option)206 	protected abstract String defineOptionName(int option);
207 
208 
209 	/**
210 	 * The inheriting option class can do additional checks on the options.
211 	 * <em>Note:</em> For performance reasons this method is only called
212 	 * when setting bitmasks directly.
213 	 * When get- and set-methods are used, this method must be called manually,
214 	 * normally only when the Options-object has been created from a client
215 	 * (it has to be made public therefore).
216 	 *
217 	 * @param options the bitmask to check.
218 	 * @throws XMPException Thrown if the options are not consistent.
219 	 */
assertConsistency(int options)220 	protected void assertConsistency(int options) throws XMPException
221 	{
222 		// empty, no checks
223 	}
224 
225 
226 	/**
227 	 * Checks options before they are set.
228 	 * First it is checked if only defined options are used,
229 	 * second the additional {@link Options#assertConsistency(int)}-method is called.
230 	 *
231 	 * @param options the options to check
232 	 * @throws XMPException Thrown if the options are invalid.
233 	 */
assertOptionsValid(int options)234 	private void assertOptionsValid(int options) throws XMPException
235 	{
236 		int invalidOptions = options & ~getValidOptions();
237 		if (invalidOptions == 0)
238 		{
239 			assertConsistency(options);
240 		}
241 		else
242 		{
243 			throw new XMPException("The option bit(s) 0x" + Integer.toHexString(invalidOptions)
244 					+ " are invalid!", XMPError.BADOPTIONS);
245 		}
246 	}
247 
248 
249 
250 	/**
251 	 * Looks up or asks the inherited class for the name of an option bit.
252 	 * Its save that there is only one valid option handed into the method.
253 	 * @param option a single option bit
254 	 * @return Returns the option name or undefined.
255 	 */
getOptionName(int option)256 	private String getOptionName(int option)
257 	{
258 		Map optionsNames = procureOptionNames();
259 
260 		Integer key = new Integer(option);
261 		String result = (String) optionsNames.get(key);
262 		if (result == null)
263 		{
264 			result = defineOptionName(option);
265 			if (result != null)
266 			{
267 				optionsNames.put(key, result);
268 			}
269 			else
270 			{
271 				result = "<option name not defined>";
272 			}
273 		}
274 
275 		return result;
276 	}
277 
278 
279 	/**
280 	 * @return Returns the optionNames map and creates it if required.
281 	 */
procureOptionNames()282 	private Map procureOptionNames()
283 	{
284 		if (optionNames == null)
285 		{
286 			optionNames = new HashMap();
287 		}
288 		return optionNames;
289 	}
290 }
291