1 // =================================================================================================
2 // ADOBE SYSTEMS INCORPORATED
3 // Copyright 2006-2007 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 com.adobe.xmp.XMPError;
13 import com.adobe.xmp.XMPException;
14 
15 
16 /**
17  * The property flags are used when properties are fetched from the <code>XMPMeta</code>-object
18  * and provide more detailed information about the property.
19  *
20  * @since   03.07.2006
21  */
22 public final class PropertyOptions extends Options
23 {
24 	/** */
25 	public static final int NO_OPTIONS = 0x00000000;
26 	/** */
27 	public static final int URI = 0x00000002;
28 	/** */
29 	public static final int HAS_QUALIFIERS = 0x00000010;
30 	/** */
31 	public static final int QUALIFIER = 0x00000020;
32 	/** */
33 	public static final int HAS_LANGUAGE = 0x00000040;
34 	/** */
35 	public static final int HAS_TYPE = 0x00000080;
36 	/** */
37 	public static final int STRUCT = 0x00000100;
38 	/** */
39 	public static final int ARRAY = 0x00000200;
40 	/** */
41 	public static final int ARRAY_ORDERED = 0x00000400;
42 	/** */
43 	public static final int ARRAY_ALTERNATE = 0x00000800;
44 	/** */
45 	public static final int ARRAY_ALT_TEXT = 0x00001000;
46 	/** */
47 	public static final int COMPACT = 0x00002000;
48 	/** */
49 	public static final int SCHEMA_NODE = 0x80000000;
50 	/** may be used in the future */
51 	public static final int DELETE_EXISTING = 0x20000000;
52 
53 
54 	/**
55 	 * Default constructor
56 	 */
PropertyOptions()57 	public PropertyOptions()
58 	{
59 		// reveal default constructor
60 	}
61 
62 
63 	/**
64 	 * Intialization constructor
65 	 *
66 	 * @param options the initialization options
67 	 * @throws XMPException If the options are not valid
68 	 */
PropertyOptions(int options)69 	public PropertyOptions(int options) throws XMPException
70 	{
71 		super(options);
72 	}
73 
74 
75 	/**
76 	 * @return Return whether the property value is a URI. It is serialized to RDF using the
77 	 *         <tt>rdf:resource</tt> attribute. Not mandatory for URIs, but considered RDF-savvy.
78 	 */
isURI()79 	public boolean isURI()
80 	{
81 		return getOption(URI);
82 	}
83 
84 
85 	/**
86 	 * @param value the value to set
87 	 * @return Returns this to enable cascaded options.
88 	 */
setURI(boolean value)89 	public PropertyOptions setURI(boolean value)
90 	{
91 		setOption(URI, value);
92 		return this;
93 	}
94 
95 
96 	/**
97 	 * @return Return whether the property has qualifiers. These could be an <tt>xml:lang</tt>
98 	 *         attribute, an <tt>rdf:type</tt> property, or a general qualifier. See the
99 	 *         introductory discussion of qualified properties for more information.
100 	 */
getHasQualifiers()101 	public boolean getHasQualifiers()
102 	{
103 		return getOption(HAS_QUALIFIERS);
104 	}
105 
106 
107 	/**
108 	 * @param value the value to set
109 	 * @return Returns this to enable cascaded options.
110 	 */
setHasQualifiers(boolean value)111 	public PropertyOptions setHasQualifiers(boolean value)
112 	{
113 		setOption(HAS_QUALIFIERS, value);
114 		return this;
115 	}
116 
117 
118 	/**
119 	 * @return Return whether this property is a qualifier for some other property. Note that if the
120 	 *         qualifier itself has a structured value, this flag is only set for the top node of
121 	 *         the qualifier's subtree. Qualifiers may have arbitrary structure, and may even have
122 	 *         qualifiers.
123 	 */
isQualifier()124 	public boolean isQualifier()
125 	{
126 		return getOption(QUALIFIER);
127 	}
128 
129 
130 	/**
131 	 * @param value the value to set
132 	 * @return Returns this to enable cascaded options.
133 	 */
setQualifier(boolean value)134 	public PropertyOptions setQualifier(boolean value)
135 	{
136 		setOption(QUALIFIER, value);
137 		return this;
138 	}
139 
140 
141 	/** @return Return whether this property has an <tt>xml:lang</tt> qualifier. */
getHasLanguage()142 	public boolean getHasLanguage()
143 	{
144 		return getOption(HAS_LANGUAGE);
145 	}
146 
147 
148 	/**
149 	 * @param value the value to set
150 	 * @return Returns this to enable cascaded options.
151 	 */
setHasLanguage(boolean value)152 	public PropertyOptions setHasLanguage(boolean value)
153 	{
154 		setOption(HAS_LANGUAGE, value);
155 		return this;
156 	}
157 
158 
159 	/** @return Return whether this property has an <tt>rdf:type</tt> qualifier. */
getHasType()160 	public boolean getHasType()
161 	{
162 		return getOption(HAS_TYPE);
163 	}
164 
165 
166 	/**
167 	 * @param value the value to set
168 	 * @return Returns this to enable cascaded options.
169 	 */
setHasType(boolean value)170 	public PropertyOptions setHasType(boolean value)
171 	{
172 		setOption(HAS_TYPE, value);
173 		return this;
174 	}
175 
176 
177 	/** @return Return whether this property contains nested fields. */
isStruct()178 	public boolean isStruct()
179 	{
180 		return getOption(STRUCT);
181 	}
182 
183 
184 	/**
185 	 * @param value the value to set
186 	 * @return Returns this to enable cascaded options.
187 	 */
setStruct(boolean value)188 	public PropertyOptions setStruct(boolean value)
189 	{
190 		setOption(STRUCT, value);
191 		return this;
192 	}
193 
194 
195 	/**
196 	 * @return Return whether this property is an array. By itself this indicates a general
197 	 *         unordered array. It is serialized using an <tt>rdf:Bag</tt> container.
198 	 */
isArray()199 	public boolean isArray()
200 	{
201 		return getOption(ARRAY);
202 	}
203 
204 
205 	/**
206 	 * @param value the value to set
207 	 * @return Returns this to enable cascaded options.
208 	 */
setArray(boolean value)209 	public PropertyOptions setArray(boolean value)
210 	{
211 		setOption(ARRAY, value);
212 		return this;
213 	}
214 
215 
216 	/**
217 	 * @return Return whether this property is an ordered array. Appears in conjunction with
218 	 *         getPropValueIsArray(). It is serialized using an <tt>rdf:Seq</tt> container.
219 	 */
isArrayOrdered()220 	public boolean isArrayOrdered()
221 	{
222 		return getOption(ARRAY_ORDERED);
223 	}
224 
225 
226 	/**
227 	 * @param value the value to set
228 	 * @return Returns this to enable cascaded options.
229 	 */
setArrayOrdered(boolean value)230 	public PropertyOptions setArrayOrdered(boolean value)
231 	{
232 		setOption(ARRAY_ORDERED, value);
233 		return this;
234 	}
235 
236 
237 	/**
238 	 * @return Return whether this property is an alternative array. Appears in conjunction with
239 	 *         getPropValueIsArray(). It is serialized using an <tt>rdf:Alt</tt> container.
240 	 */
isArrayAlternate()241 	public boolean isArrayAlternate()
242 	{
243 		return getOption(ARRAY_ALTERNATE);
244 	}
245 
246 
247 	/**
248 	 * @param value the value to set
249 	 * @return Returns this to enable cascaded options.
250 	 */
setArrayAlternate(boolean value)251 	public PropertyOptions setArrayAlternate(boolean value)
252 	{
253 		setOption(ARRAY_ALTERNATE, value);
254 		return this;
255 	}
256 
257 
258 	/**
259 	 * @return Return whether this property is an alt-text array. Appears in conjunction with
260 	 *         getPropArrayIsAlternate(). It is serialized using an <tt>rdf:Alt</tt> container.
261 	 *         Each array element is a simple property with an <tt>xml:lang</tt> attribute.
262 	 */
isArrayAltText()263 	public boolean isArrayAltText()
264 	{
265 		return getOption(ARRAY_ALT_TEXT);
266 	}
267 
268 
269 	/**
270 	 * @param value the value to set
271 	 * @return Returns this to enable cascaded options.
272 	 */
setArrayAltText(boolean value)273 	public PropertyOptions setArrayAltText(boolean value)
274 	{
275 		setOption(ARRAY_ALT_TEXT, value);
276 		return this;
277 	}
278 
279 
280 	/**
281 	 * @return Return whether the value is a compact struct or array.
282 	 */
isCompact()283 	public boolean isCompact()
284 	{
285 		return getOption(COMPACT);
286 	}
287 
288 
289 	/**
290 	 * @param value the value to set
291 	 * @return Returns this to enable cascaded options.
292 	 */
setCompact(boolean value)293 	public PropertyOptions setCompact(boolean value)
294 	{
295 		setOption(COMPACT, value);
296 		return this;
297 	}
298 
299 
300 	/**
301 	 * @param value the value to set
302 	 * @return Returns this to enable cascaded options.
303 	 */
304 
305 
306 	/**
307 	 * @return Returns whether the SCHEMA_NODE option is set.
308 	 */
isSchemaNode()309 	public boolean isSchemaNode()
310 	{
311 		return getOption(SCHEMA_NODE);
312 	}
313 
314 
315 	/**
316 	 * @param value the option DELETE_EXISTING to set
317 	 * @return Returns this to enable cascaded options.
318 	 */
setSchemaNode(boolean value)319 	public PropertyOptions setSchemaNode(boolean value)
320 	{
321 		setOption(SCHEMA_NODE, value);
322 		return this;
323 	}
324 
325 
326 	//-------------------------------------------------------------------------- convenience methods
327 
328 	/**
329 	 * @return Returns whether the property is of composite type - an array or a struct.
330 	 */
isCompositeProperty()331 	public boolean isCompositeProperty()
332 	{
333 		return (getOptions() & (ARRAY | STRUCT)) > 0;
334 	}
335 
336 
337 	/**
338 	 * @return Returns whether the property is of composite type - an array or a struct.
339 	 */
isSimple()340 	public boolean isSimple()
341 	{
342 		return (getOptions() & (ARRAY | STRUCT)) == 0;
343 	}
344 
345 
346 	/**
347 	 * Compares two options set for array compatibility.
348 	 *
349 	 * @param options other options
350 	 * @return Returns true if the array options of the sets are equal.
351 	 */
equalArrayTypes(PropertyOptions options)352 	public boolean equalArrayTypes(PropertyOptions options)
353 	{
354 		return
355 			isArray()			== options.isArray()  			&&
356 			isArrayOrdered()	== options.isArrayOrdered()  	&&
357 			isArrayAlternate()	== options.isArrayAlternate()	&&
358 			isArrayAltText()	== options.isArrayAltText();
359 	}
360 
361 
362 
363 	/**
364 	 * Merges the set options of a another options object with this.
365 	 * If the other options set is null, this objects stays the same.
366 	 * @param options other options
367 	 * @throws XMPException If illegal options are provided
368 	 */
mergeWith(PropertyOptions options)369 	public void mergeWith(PropertyOptions options) throws XMPException
370 	{
371 		if (options != null)
372 		{
373 			setOptions(getOptions() | options.getOptions());
374 		}
375 	}
376 
377 
378 	/**
379 	 * @return Returns true if only array options are set.
380 	 */
isOnlyArrayOptions()381 	public boolean isOnlyArrayOptions()
382 	{
383 		return (getOptions() &
384 			~(ARRAY | ARRAY_ORDERED | ARRAY_ALTERNATE | ARRAY_ALT_TEXT)) == 0;
385 	}
386 
387 
388 	/**
389 	 * @see Options#getValidOptions()
390 	 */
getValidOptions()391 	protected int getValidOptions()
392 	{
393 		return
394 			URI |
395 			HAS_QUALIFIERS |
396 			QUALIFIER |
397 			HAS_LANGUAGE |
398 			HAS_TYPE |
399 			STRUCT |
400 			ARRAY |
401 			ARRAY_ORDERED |
402 			ARRAY_ALTERNATE |
403 			ARRAY_ALT_TEXT |
404 			COMPACT |
405 			SCHEMA_NODE;
406 	}
407 
408 
409 	/**
410 	 * @see Options#defineOptionName(int)
411 	 */
defineOptionName(int option)412 	protected String defineOptionName(int option)
413 	{
414 		switch (option)
415 		{
416 			case URI : 			return "URI";
417 			case HAS_QUALIFIERS :	return "HAS_QUALIFIER";
418 			case QUALIFIER :		return "QUALIFIER";
419 			case HAS_LANGUAGE :	return "HAS_LANGUAGE";
420 			case HAS_TYPE:		return "HAS_TYPE";
421 			case STRUCT :			return "STRUCT";
422 			case ARRAY :			return "ARRAY";
423 			case ARRAY_ORDERED :	return "ARRAY_ORDERED";
424 			case ARRAY_ALTERNATE :	return "ARRAY_ALTERNATE";
425 			case ARRAY_ALT_TEXT : 	return "ARRAY_ALT_TEXT";
426 			case COMPACT : 		return "COMPACT";
427 			case SCHEMA_NODE : 			return "SCHEMA_NODE";
428 			default: 					return null;
429 		}
430 	}
431 
432 
433 	/**
434 	 * Checks that a node not a struct and array at the same time;
435 	 * and URI cannot be a struct.
436 	 *
437 	 * @param options the bitmask to check.
438 	 * @throws XMPException Thrown if the options are not consistent.
439 	 */
assertConsistency(int options)440 	public void assertConsistency(int options) throws XMPException
441 	{
442 		if ((options & STRUCT) > 0  &&  (options & ARRAY) > 0)
443 		{
444 			throw new XMPException("IsStruct and IsArray options are mutually exclusive",
445 					XMPError.BADOPTIONS);
446 		}
447 		else if ((options & URI) > 0  &&  (options & (ARRAY | STRUCT)) > 0)
448 		{
449 			throw new XMPException("Structs and arrays can't have \"value\" options",
450 				XMPError.BADOPTIONS);
451 		}
452 	}
453 }