View Javadoc

1   /*
2    * $HeadURL: $
3    * $Date: $
4    * $Revision: $
5    * $Author: $
6    * 
7    * Copyright (c) 2005 MindTree Consulting Ltd. 
8    * 
9    * This file is part of Insight.
10   * 
11   * Insight is free software: you can redistribute it and/or modify it under the 
12   * terms of the GNU General Public License as published by the Free Software 
13   * Foundation, either version 3 of the License, or (at your option) any later 
14   * version.
15   * 
16   * Insight is distributed in the hope that it will be useful, but 
17   * WITHOUT ANY WARRANTY; without even the implied warranty of 
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
19   * Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public License along with 
22   * Insight.  If not, see <http://www.gnu.org/licenses/>.
23   */
24  
25  package com.mindtree.techworks.insight.preferences.model;
26  
27  import java.io.Serializable;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  
31  
32  /**
33   * This class stores a list of Preference attributes. It has a unique identifier
34   * and name. No preference attribute can exist without a preference.
35   * 
36   * @see PreferenceAttribute PreferenceAttribute
37   * @author Bindul Bhowmik
38   * @version $Revision: 27 $ $Date: 2007-12-16 04:58:03 -0700 (Sun, 16 Dec 2007) $
39   */
40  public class Preference implements Serializable {
41  
42  	/**
43  	 * Used for object serialization
44  	 */
45  	private static final long serialVersionUID = -9070247330487678727L;
46  
47  	/**
48  	 * Seperator between the IDs of parent and child Preferences
49  	 */
50  	public static final String ID_SEPERATOR = "@";
51  
52  	/**
53  	 * The unique identifier for the Preference
54  	 */
55  	private String id;
56  
57  	/**
58  	 * The display name of the Preference
59  	 */
60  	private String name;
61  
62  	/**
63  	 * Is the preference user modifiable. If the value of this field is set to
64  	 * false, it overrides any value set for user modifiable in child
65  	 * PreferenceAttributes of this object, and they will all be considered to
66  	 * have their userModifiable field set to false.
67  	 * 
68  	 * @see PreferenceAttribute#isUserModifiable() isUserModifiable in
69  	 *      PreferenceAttribute
70  	 */
71  	private boolean isUserModifiable;
72  
73  	/**
74  	 * If this preference is a child of another preference, the reference to the
75  	 * parent preference is stored here.
76  	 */
77  	private Preference parentPreference;
78  
79  	/**
80  	 * Contains a list of child Preferences of this preference.
81  	 */
82  	private HashMap childPreferences;
83  
84  	/**
85  	 * Child PreferenceAttributes for this Preference.
86  	 */
87  	private HashMap preferenceAttributes;
88  
89  	/**
90  	 * The display class used by the GUI for displaying preferences.
91  	 */
92  	private String displayClass;
93  
94  	/**
95  	 * If this is an aggregated attribute, in which case, it won't show up in
96  	 * the tree of the Preference GUI.
97  	 */
98  	private boolean isAggregated;
99  
100 	/**
101 	 * The manager of the Application. The preference notifies the manager for
102 	 * any change in values of its attributes using this instance.
103 	 */
104 	private transient PreferenceModelManager preferenceModelManager;
105 
106 	/**
107 	 * Constructor which sets the fields.
108 	 * 
109 	 * @param id The unique identifier for the Preference
110 	 * @param isUserModifiable s the preference user modifiable
111 	 * @param isAggregated If this is an aggregated preference.
112 	 */
113 	public Preference (String id, boolean isUserModifiable, boolean isAggregated) {
114 
115 		this.id = id;
116 		this.isUserModifiable = isUserModifiable;
117 		this.isAggregated = isAggregated;
118 		preferenceAttributes = new HashMap();
119 	}
120 
121 	/**
122 	 * Utility constructor which sets the display name also
123 	 * 
124 	 * @param id The unique identifier for the Preference
125 	 * @param isUserModifiable s the preference user modifiable
126 	 * @param isAggregated If this is an aggregated preference.
127 	 * @param name The display name of the Preference
128 	 */
129 	public Preference (String id, boolean isUserModifiable,
130 			boolean isAggregated, String name) {
131 
132 		this(id, isUserModifiable, isAggregated);
133 		this.name = name;
134 	}
135 
136 
137 	/**
138 	 * @return Returns the isAggregated.
139 	 */
140 	public boolean isAggregated () {
141 
142 		return isAggregated;
143 	}
144 
145 	/**
146 	 * @return Returns the id.
147 	 */
148 	public String getId () {
149 
150 		return id;
151 	}
152 
153 	/**
154 	 * Returns the complete Id of the preference, including the parent's id. The
155 	 * id is of the form:
156 	 * 
157 	 * <pre>
158 	 * PARENTID_CHILDID
159 	 * </pre>
160 	 * 
161 	 * @see Preference#ID_SEPERATOR Seperator between two IDs
162 	 * @return The complete id of the Preference
163 	 */
164 	public String getCompleteId () {
165 
166 		if (null == parentPreference) {
167 			return id;
168 		} else {
169 			return parentPreference.getCompleteId() + ID_SEPERATOR + id;
170 		}
171 	}
172 
173 	/**
174 	 * @return Returns the isUserModifiable.
175 	 */
176 	public boolean isUserModifiable () {
177 
178 		return isUserModifiable;
179 	}
180 
181 	/**
182 	 * @return Returns the name.
183 	 */
184 	public String getName () {
185 
186 		return name;
187 	}
188 
189 	/**
190 	 * Adds a preferenceAttribute to the Preference. If a preference already
191 	 * exists with the id of the PreferenceAttribute passed, the addition will
192 	 * fail. Also if the parent of the preference is not this object, then also
193 	 * addition fails.
194 	 * 
195 	 * @param preferenceAttribute The <code>PreferenceAttribute</code> to add.
196 	 * @return <code>true</code> if the addition is succesfull or
197 	 *         <code>false</code>
198 	 */
199 	public boolean addPreferenceAttribute (
200 			PreferenceAttribute preferenceAttribute) {
201 
202 		if (preferenceAttributes.containsKey(preferenceAttribute.getId())) {
203 			return false;
204 		} else if (!this.equals(preferenceAttribute.getParent())) {
205 			return false;
206 		} else {
207 			preferenceAttributes.put(preferenceAttribute.getId(),
208 					preferenceAttribute);
209 			if (null != preferenceModelManager) {
210 				if (null != preferenceModelManager) {
211 					preferenceModelManager.preferenceAttributeChanged(this.getCompleteId(), preferenceAttribute.getId(), PreferenceModelManager.OPERATION_PREF_ATTR_ADDED);
212 				}
213 			}
214 			return true;
215 		}
216 	}
217 
218 	/**
219 	 * Registers the manager for this preference. Checks if any other manager is
220 	 * already registered with the instance.
221 	 * 
222 	 * @param manager The preferenceModelManager to set.
223 	 * @return <code>true</code> if the registration succeeds or
224 	 *         <code>false</code>
225 	 */
226 	public boolean registerPreferenceModelManager (
227 			PreferenceModelManager manager) {
228 
229 		if (null == preferenceModelManager) {
230 			preferenceModelManager = manager;
231 			// Register children...
232 			if (null != childPreferences) {
233 				Iterator childPreferenceItr = childPreferences.values()
234 						.iterator();
235 				while (childPreferenceItr.hasNext()) {
236 					Preference childPreference = (Preference) childPreferenceItr
237 							.next();
238 					childPreference.registerPreferenceModelManager(manager);
239 				}
240 			}
241 			return true;
242 		} else {
243 			return false;
244 		}
245 	}
246 
247 	/**
248 	 * Deregisters the manager from this preference. Does a check to see if the
249 	 * manager being asked to be deregistered is the one registered for
250 	 * notifications.
251 	 * 
252 	 * @param manager The manager to deregister
253 	 * @return <code>true</code> if the deregistration succeeds or
254 	 *         <code>false</code>
255 	 */
256 	public boolean deregisterPreferenceModelManager (
257 			PreferenceModelManager manager) {
258 
259 		if (null != preferenceModelManager
260 				&& preferenceModelManager.equals(manager)) {
261 			preferenceModelManager = null;
262 			// DeRegister children...
263 			if (null != childPreferences) {
264 				Iterator childPreferenceItr = childPreferences.values()
265 						.iterator();
266 				while (childPreferenceItr.hasNext()) {
267 					Preference childPreference = (Preference) childPreferenceItr
268 							.next();
269 					childPreference.deregisterPreferenceModelManager(manager);
270 				}
271 			}
272 			return true;
273 		} else {
274 			return false;
275 		}
276 	}
277 
278 	/**
279 	 * Method called by the attributes to notify of a value change
280 	 * 
281 	 * @param attributeId The attribute whose value changed
282 	 * @param newValue The new value of the attribute
283 	 */
284 	void notifyAttributeValueChange (String attributeId, String newValue) {
285 
286 		// Notification is done with the complete id.
287 		if (null != preferenceModelManager
288 				&& preferenceAttributes.containsKey(attributeId)) {
289 			preferenceModelManager.attributeValueChanged(getCompleteId(),
290 					attributeId, newValue);
291 		}
292 	}
293 
294 	/**
295 	 * Returns a PreferenceAttribute for the id specified. Searches also the
296 	 * parent preferences for the attribute.
297 	 * 
298 	 * @param attributeId The id of the attribute
299 	 * @return PreferenceAttribute for the id supplied.
300 	 * @throws ArrayIndexOutOfBoundsException If the id is not found.
301 	 */
302 	public PreferenceAttribute getPreferenceAttributeById (String attributeId) {
303 
304 		if (preferenceAttributes.containsKey(attributeId)) {
305 			return (PreferenceAttribute) preferenceAttributes.get(attributeId);
306 		} else if (null != parentPreference) {
307 			return parentPreference.getPreferenceAttributeById(attributeId);
308 		} else {
309 			throw new ArrayIndexOutOfBoundsException(
310 					"Preference Attribute not present");
311 		}
312 	}
313 
314 	/**
315 	 * Checks if the preference has an attribute with the attribute id. Checks
316 	 * the parent preference also for the attribute.
317 	 * 
318 	 * @param attributeId The id to check
319 	 * @return <code>true</code> if the attribute is present or
320 	 *         <code>false</code>
321 	 */
322 	public boolean isPreferenceAttributePresent (String attributeId) {
323 
324 		if (preferenceAttributes.containsKey(attributeId)) {
325 			return true;
326 		} else if (null != parentPreference) {
327 			return parentPreference.isPreferenceAttributePresent(attributeId);
328 		} else {
329 			return false;
330 		}
331 	}
332 
333 	/**
334 	 * Returns an iterator for all the Preference Attributes.
335 	 * 
336 	 * @return <code>Iterator</code> for all the Preference Attribtues.
337 	 */
338 	public Iterator iteratePreferenceAttributes () {
339 
340 		return preferenceAttributes.values().iterator();
341 	}
342 
343 	/**
344 	 * Returns an iterator for the ids of all the Preference Attribtues in this
345 	 * Preference.
346 	 * 
347 	 * @return <code>Iterator</code> for all the Preference Attribute Keys.
348 	 */
349 	public Iterator iteratePreferenceAttributeIds () {
350 
351 		return preferenceAttributes.keySet().iterator();
352 	}
353 
354 	/**
355 	 * Returns a child preference for the Id passed
356 	 * 
357 	 * @param preferenceId The id of the preference required.
358 	 * @return Preference for the id passed.
359 	 * @throws ArrayIndexOutOfBoundsException If the Preference for the id
360 	 *             passed is not present.
361 	 */
362 	public Preference getPreferenceById (String preferenceId) {
363 
364 		if (null != childPreferences) {
365 			if (childPreferences.containsKey(preferenceId)) {
366 				return (Preference) childPreferences.get(preferenceId);
367 			} else if (preferenceId.indexOf(ID_SEPERATOR) > 0) {
368 				int parentLocation = preferenceId.indexOf(ID_SEPERATOR);
369 				String parentKey = preferenceId.substring(0, parentLocation);
370 				
371 				if (childPreferences.containsKey(parentKey)) {
372 					return ((Preference) childPreferences.get(parentKey)).getPreferenceById(preferenceId.substring(parentLocation + 1));
373 				} else {
374 					throw new ArrayIndexOutOfBoundsException("Preference not present");
375 				}
376 			} else {
377 				throw new ArrayIndexOutOfBoundsException("Preference not present");
378 			}
379 		} else {
380 			throw new ArrayIndexOutOfBoundsException("Preference not present");
381 		}
382 	}
383 
384 	/**
385 	 * Checks if the Preference with the id specified is a child of this
386 	 * preference.
387 	 * 
388 	 * @param preferenceId The id of the child preference to check.
389 	 * @return <code>true</code> if the preference is present or
390 	 *         <code>false</code>
391 	 */
392 	public boolean isPreferencePresent (String preferenceId) {
393 
394 		if (null != childPreferences) {
395 			return childPreferences.containsKey(preferenceId);
396 		} else {
397 			return false;
398 		}
399 
400 	}
401 
402 	/**
403 	 * Returns an iterator to the child Preferences.
404 	 * 
405 	 * @return An iterator of the child preferences or <code>null</code> if
406 	 *         none are present.
407 	 */
408 	public Iterator iterateChildPreferences () {
409 
410 		if (null != childPreferences) {
411 			return childPreferences.values().iterator();
412 		} else {
413 			return null;
414 		}
415 	}
416 
417 	/**
418 	 * Returns an iterator to the child Preference ids.
419 	 * 
420 	 * @return An iterator of the child preference ids or <code>null</code> if
421 	 *         none are present.
422 	 */
423 	public Iterator iterateChildPreferenceIds () {
424 
425 		if (null != childPreferences) {
426 			return childPreferences.keySet().iterator();
427 		} else {
428 			return null;
429 		}
430 	}
431 
432 	/**
433 	 * Constructs and returns a PreferenceInfo object for this instance.
434 	 * 
435 	 * @see PreferenceInfo PreferenceInfo
436 	 * @return PreferenceInfo for this object.
437 	 */
438 	public PreferenceInfo getPreferenceInfo () {
439 
440 		PreferenceInfo preferenceInfo = new PreferenceInfo();
441 		preferenceInfo.setId(this.id);
442 		preferenceInfo.setName(this.name);
443 		preferenceInfo.setUserModifiable(this.isUserModifiable);
444 		preferenceInfo.setAggregated(this.isAggregated);
445 		preferenceInfo.setCompleteId(getCompleteId());
446 
447 		// Get child preference info's
448 		if (null != childPreferences) {
449 			for (Iterator childPrefItr = childPreferences.values().iterator(); childPrefItr
450 					.hasNext();) {
451 				preferenceInfo
452 						.addChildPreferenceInfo(((Preference) childPrefItr
453 								.next()).getPreferenceInfo());
454 			}
455 		}
456 
457 		return preferenceInfo;
458 	}
459 
460 	/**
461 	 * @return Returns the displayClass.
462 	 */
463 	public String getDisplayClass () {
464 
465 		return displayClass;
466 	}
467 
468 	/**
469 	 * @param displayClass The displayClass to set.
470 	 */
471 	public void setDisplayClass (String displayClass) {
472 
473 		this.displayClass = displayClass;
474 	}
475 
476 	/**
477 	 * Sets the parent preference of this preference
478 	 * 
479 	 * @param parentPreference Parent preference
480 	 */
481 	protected void setParent (Preference parentPreference) {
482 
483 		this.parentPreference = parentPreference;
484 	}
485 
486 	/**
487 	 * Adds a child preference to this preference
488 	 * 
489 	 * @param preference The preference to add
490 	 * @return <code>true</code> If preference is added successfully or
491 	 *         <code>false</code>
492 	 */
493 	public boolean addChildPreference (Preference preference) {
494 
495 		if (null == childPreferences) {
496 			childPreferences = new HashMap();
497 		}
498 
499 		if (childPreferences.containsKey(preference.getId())) {
500 			return false;
501 		} else {
502 			childPreferences.put(preference.getId(), preference);
503 			preference.setParent(this);
504 			if (null != preferenceModelManager) {
505 				preference
506 						.registerPreferenceModelManager(preferenceModelManager);
507 				// Send notification
508 				preferenceModelManager.childPreferenceChanged(this
509 						.getCompleteId(), preference.getId(),
510 						PreferenceModelManager.OPERATION_CHILD_PREF_ADDED);
511 			}
512 			return true;
513 		}
514 	}
515 	
516 	/**
517 	 * Removes a child preference
518 	 * @param preference The preference to remove
519 	 * @return <code>true</code> if remove succeeds or <code>false</code>.
520 	 */
521 	public boolean removePreference(Preference preference) {
522 		if (preference.parentPreference == this) {
523 			if (null != childPreferences && childPreferences.containsKey(preference.getId())) {
524 				childPreferences.remove(preference.getId());
525 				preference.deregisterPreferenceModelManager(this.preferenceModelManager);
526 				preference.parentPreference = null;
527 				// Send Notification
528 				if (null != preferenceModelManager) {
529 					preferenceModelManager
530 							.childPreferenceChanged(
531 									this.getCompleteId(),
532 									preference.getId(),
533 									PreferenceModelManager.OPERATION_CHILD_PREF_REMOVED);
534 				}
535 				return true;
536 			} else {
537 				return false;
538 			}
539 		} else {
540 			return false;
541 		}
542 	}
543 	
544 	/**
545 	 * Removes a preference attribute from this preference
546 	 * @param preferenceAttribute The preferenceAttribute to remove
547 	 * @return <code>true</code> if the removal succeeds or <code>false</code>.
548 	 */
549 	public boolean removePreferenceAttribute(PreferenceAttribute preferenceAttribute) {
550 		if (preferenceAttribute.getParent().equals(this) && this.preferenceAttributes.containsValue(preferenceAttribute)) {
551 			this.preferenceAttributes.remove(preferenceAttribute.getId());
552 			if (null != preferenceModelManager) {
553 				preferenceModelManager.preferenceAttributeChanged(this.getCompleteId(), preferenceAttribute.getId(), PreferenceModelManager.OPERATION_PREF_ATTR_REMOVED);
554 			}
555 			return true;
556 		} else {
557 			return false;
558 		}
559 	}
560 	/**
561 	 * @param name The name to set.
562 	 */
563 	public void setName(String name) {
564 		this.name = name;
565 	}
566 }