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